Fix build break caused by adding DebugAgentLib to the DXE Core.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Fv.py
CommitLineData
30fdf114
LG
1## @file\r
2# process FV generation\r
3#\r
4# Copyright (c) 2007, Intel Corporation\r
5#\r
6# All rights reserved. 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 os\r
19import shutil\r
20import subprocess\r
21import StringIO\r
b303ea72 22from struct import *\r
30fdf114
LG
23\r
24import Ffs\r
25import AprioriSection\r
26from GenFdsGlobalVariable import GenFdsGlobalVariable\r
27from GenFds import GenFds\r
28from CommonDataClass.FdfClass import FvClassObject\r
29from Common.Misc import SaveFileOnChange\r
30\r
31T_CHAR_LF = '\n'\r
32\r
33## generate FV\r
34#\r
35#\r
36class FV (FvClassObject):\r
37 ## The constructor\r
38 #\r
39 # @param self The object pointer\r
40 #\r
41 def __init__(self):\r
42 FvClassObject.__init__(self)\r
43 self.FvInfFile = None\r
44 self.FvAddressFile = None\r
45 self.BaseAddress = None\r
46 self.InfFileName = None\r
47 self.FvAddressFileName = None\r
fd171542 48 self.CapsuleName = None\r
30fdf114
LG
49\r
50 ## AddToBuffer()\r
51 #\r
52 # Generate Fv and add it to the Buffer\r
53 #\r
54 # @param self The object pointer\r
55 # @param Buffer The buffer generated FV data will be put\r
56 # @param BaseAddress base address of FV\r
57 # @param BlockSize block size of FV\r
58 # @param BlockNum How many blocks in FV\r
59 # @param ErasePolarity Flash erase polarity\r
60 # @param VtfDict VTF objects\r
61 # @param MacroDict macro value pair\r
62 # @retval string Generated FV file path\r
63 #\r
64 def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :\r
65\r
fd171542 66 if self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
67 return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']\r
68 \r
69 #\r
70 # Check whether FV in Capsule is in FD flash region.\r
71 # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.\r
72 #\r
73 if self.CapsuleName != None:\r
b303ea72
LG
74 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
75 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
fd171542 76 for RegionObj in FdObj.RegionList:\r
77 if RegionObj.RegionType == 'FV':\r
78 for RegionData in RegionObj.RegionDataList:\r
79 if RegionData.endswith(".fv"):\r
80 continue\r
81 elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
82 continue\r
83 elif self.UiFvName.upper() == RegionData.upper():\r
84 GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))\r
30fdf114 85\r
fd171542 86 GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)\r
30fdf114
LG
87\r
88 self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)\r
89 #\r
90 # First Process the Apriori section\r
91 #\r
92 MacroDict.update(self.DefineVarDict)\r
93\r
94 GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')\r
95 FfsFileList = []\r
96 for AprSection in self.AprioriSectionList:\r
97 FileName = AprSection.GenFfs (self.UiFvName, MacroDict)\r
98 FfsFileList.append(FileName)\r
99 # Add Apriori file name to Inf file\r
100 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
101 FileName + \\r
102 T_CHAR_LF)\r
103\r
104 # Process Modules in FfsList\r
105 for FfsFile in self.FfsList :\r
106 FileName = FfsFile.GenFfs(MacroDict)\r
107 FfsFileList.append(FileName)\r
108 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
109 FileName + \\r
110 T_CHAR_LF)\r
111\r
112 SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)\r
113 self.FvInfFile.close()\r
114 #\r
115 # Call GenFv tool\r
116 #\r
117 FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)\r
118 FvOutputFile = FvOutputFile + '.Fv'\r
119 # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)\r
120 if self.CreateFileName != None:\r
121 FvOutputFile = self.CreateFileName\r
122\r
123 FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')\r
124 shutil.copy(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)\r
125 GenFdsGlobalVariable.GenerateFirmwareVolume(\r
126 FvOutputFile,\r
127 [self.InfFileName],\r
128 AddressFile=FvInfoFileName,\r
129 FfsList=FfsFileList\r
130 )\r
131\r
132 #\r
133 # Write the Fv contents to Buffer\r
134 #\r
135 FvFileObj = open ( FvOutputFile,'r+b')\r
136\r
fd171542 137 GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName)\r
30fdf114
LG
138 GenFdsGlobalVariable.SharpCounter = 0\r
139\r
140 Buffer.write(FvFileObj.read())\r
141 FvFileObj.close()\r
fd171542 142 GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile\r
30fdf114
LG
143 return FvOutputFile\r
144\r
145 ## __InitializeInf__()\r
146 #\r
147 # Initilize the inf file to create FV\r
148 #\r
149 # @param self The object pointer\r
150 # @param BaseAddress base address of FV\r
151 # @param BlockSize block size of FV\r
152 # @param BlockNum How many blocks in FV\r
153 # @param ErasePolarity Flash erase polarity\r
154 # @param VtfDict VTF objects\r
155 #\r
156 def __InitializeInf__ (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1', VtfDict=None) :\r
157 #\r
158 # Create FV inf file\r
159 #\r
160 self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir,\r
161 self.UiFvName + '.inf')\r
162 self.FvInfFile = StringIO.StringIO()\r
163\r
164 #\r
165 # Add [Options]\r
166 #\r
167 self.FvInfFile.writelines("[options]" + T_CHAR_LF)\r
168 if BaseAddress != None :\r
169 self.FvInfFile.writelines("EFI_BASE_ADDRESS = " + \\r
170 BaseAddress + \\r
171 T_CHAR_LF)\r
172\r
173 if BlockSize != None:\r
174 self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \\r
175 '0x%X' %BlockSize + \\r
176 T_CHAR_LF)\r
177 if BlockNum != None:\r
178 self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \\r
179 ' 0x%X' %BlockNum + \\r
180 T_CHAR_LF)\r
181 else:\r
182 for BlockSize in self.BlockSizeList :\r
183 if BlockSize[0] != None:\r
184 self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \\r
185 '0x%X' %BlockSize[0] + \\r
186 T_CHAR_LF)\r
187\r
188 if BlockSize[1] != None:\r
189 self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \\r
190 ' 0x%X' %BlockSize[1] + \\r
191 T_CHAR_LF)\r
192\r
193 if self.BsBaseAddress != None:\r
194 self.FvInfFile.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \\r
195 '0x%X' %self.BsBaseAddress)\r
196 if self.RtBaseAddress != None:\r
197 self.FvInfFile.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \\r
198 '0x%X' %self.RtBaseAddress)\r
199 #\r
200 # Add attribute\r
201 #\r
202 self.FvInfFile.writelines("[attributes]" + T_CHAR_LF)\r
203\r
204 self.FvInfFile.writelines("EFI_ERASE_POLARITY = " + \\r
205 ' %s' %ErasePloarity + \\r
206 T_CHAR_LF)\r
207 if not (self.FvAttributeDict == None):\r
208 for FvAttribute in self.FvAttributeDict.keys() :\r
209 self.FvInfFile.writelines("EFI_" + \\r
210 FvAttribute + \\r
211 ' = ' + \\r
212 self.FvAttributeDict[FvAttribute] + \\r
213 T_CHAR_LF )\r
214 if self.FvAlignment != None:\r
215 self.FvInfFile.writelines("EFI_FVB2_ALIGNMENT_" + \\r
216 self.FvAlignment.strip() + \\r
217 " = TRUE" + \\r
218 T_CHAR_LF)\r
b303ea72 219 \r
30fdf114 220 #\r
b303ea72 221 # Generate FV extension header file\r
30fdf114 222 #\r
b303ea72
LG
223 if self.FvNameGuid == None or self.FvNameGuid == '':\r
224 if len(self.FvExtEntryType) > 0:\r
225 GenFdsGlobalVariable.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self.UiFvName))\r
226 \r
227 if self.FvNameGuid <> None and self.FvNameGuid <> '':\r
228 TotalSize = 16 + 4\r
229 Buffer = ''\r
230 for Index in range (0, len(self.FvExtEntryType)):\r
231 if self.FvExtEntryType[Index] == 'FILE':\r
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])
235 else:
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]))\r
240 FvExtFile = open (FileFullPath,'rb')\r
241 FvExtFile.seek(0,2)\r
242 Size = FvExtFile.tell()\r
243 if Size >= 0x10000:\r
244 GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self.FvExtEntryData[Index]))\r
245 TotalSize += (Size + 4)\r
246 FvExtFile.seek(0)\r
247 Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))\r
248 Buffer += FvExtFile.read() \r
249 FvExtFile.close()\r
250 if self.FvExtEntryType[Index] == 'DATA':\r
251 ByteList = self.FvExtEntryData[Index].split(',')\r
252 Size = len (ByteList)\r
253 if Size >= 0x10000:\r
254 GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self.FvExtEntryData[Index]))\r
255 TotalSize += (Size + 4)\r
256 Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))\r
257 for Index1 in range (0, Size):\r
258 Buffer += pack('B', int(ByteList[Index1], 16))\r
259\r
260 Guid = self.FvNameGuid.split('-')\r
261 Buffer = pack('LHHBBBBBBBBL', \r
262 int(Guid[0], 16), \r
263 int(Guid[1], 16), \r
264 int(Guid[2], 16), \r
265 int(Guid[3][-4:-2], 16), \r
266 int(Guid[3][-2:], 16), \r
267 int(Guid[4][-12:-10], 16),\r
268 int(Guid[4][-10:-8], 16),\r
269 int(Guid[4][-8:-6], 16),\r
270 int(Guid[4][-6:-4], 16),\r
271 int(Guid[4][-4:-2], 16),\r
272 int(Guid[4][-2:], 16),\r
273 TotalSize\r
274 ) + Buffer\r
275\r
276 #\r
277 # Generate FV extension header file if the total size is not zero\r
278 #\r
279 if TotalSize > 0:\r
280 FvExtHeaderFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName + '.ext')\r
a709adfa 281 FvExtHeaderFile = StringIO.StringIO()\r
b303ea72 282 FvExtHeaderFile.write(Buffer)\r
a709adfa 283 Changed = SaveFileOnChange(FvExtHeaderFileName, FvExtHeaderFile.getvalue(), True)\r
b303ea72 284 FvExtHeaderFile.close()\r
a709adfa
LG
285 if Changed:\r
286 if os.path.exists (self.InfFileName):\r
287 os.remove (self.InfFileName)\r
b303ea72
LG
288 self.FvInfFile.writelines("EFI_FV_EXT_HEADER_FILE_NAME = " + \\r
289 FvExtHeaderFileName + \\r
290 T_CHAR_LF)\r
30fdf114 291\r
b303ea72
LG
292 \r
293 #\r
294 # Add [Files]\r
295 #\r
30fdf114
LG
296 self.FvInfFile.writelines("[files]" + T_CHAR_LF)\r
297 if VtfDict != None and self.UiFvName in VtfDict.keys():\r
298 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
299 VtfDict.get(self.UiFvName) + \\r
300 T_CHAR_LF)\r