]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools: Enhance GenFv Tool to report error message
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
CommitLineData
30fdf114
LG
1## @file\r
2# process FFS generation from INF statement\r
3#\r
22a99b87 4# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
0acb3d28 5# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16##\r
17# Import Modules\r
18#\r
19import Rule\r
1be2ed90 20import Common.LongFilePathOs as os\r
da92f276
LG
21import StringIO\r
22from struct import *\r
30fdf114
LG
23from GenFdsGlobalVariable import GenFdsGlobalVariable\r
24import Ffs\r
25import subprocess\r
26import sys\r
27import Section\r
28import RuleSimpleFile\r
29import RuleComplexFile\r
30from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
05cc51ad 31from Common.MultipleWorkspace import MultipleWorkspace as mws\r
30fdf114
LG
32from Common.String import *\r
33from Common.Misc import PathClass\r
34from Common.Misc import GuidStructureByteArrayToGuidString\r
97fa0ee9 35from Common.Misc import ProcessDuplicatedInf\r
22a99b87 36from Common.Misc import GetVariableOffset\r
30fdf114
LG
37from Common import EdkLogger\r
38from Common.BuildToolError import *\r
52302d4d
LG
39from GuidSection import GuidSection\r
40from FvImageSection import FvImageSection\r
41from Common.Misc import PeImageClass\r
b36d134f 42from AutoGen.GenDepex import DependencyExpression\r
e8a47801 43from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
1be2ed90
HC
44from Common.LongFilePathSupport import CopyLongFilePath\r
45from Common.LongFilePathSupport import OpenLongFilePath as open\r
30fdf114
LG
46\r
47## generate FFS from INF\r
48#\r
49#\r
50class FfsInfStatement(FfsInfStatementClassObject):\r
2bc3256c
LG
51 ## The mapping dictionary from datum type to its maximum number.\r
52 _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}\r
30fdf114
LG
53 ## The constructor\r
54 #\r
55 # @param self The object pointer\r
56 #\r
57 def __init__(self):\r
58 FfsInfStatementClassObject.__init__(self)\r
59 self.TargetOverrideList = []\r
60 self.ShadowFromInfFile = None\r
61 self.KeepRelocFromRule = None\r
62 self.InDsc = True\r
63 self.OptRomDefs = {}\r
da92f276 64 self.PiSpecVersion = '0x00000000'\r
4234283c 65 self.InfModule = None\r
b36d134f 66 self.FinalTargetSuffixMap = {}\r
79b74a03
LG
67 self.CurrentLineNum = None\r
68 self.CurrentLineContent = None\r
69 self.FileName = None\r
70 self.InfFileName = None\r
97fa0ee9
YL
71 self.OverrideGuid = None\r
72 self.PatchedBinFile = ''\r
7ae7dcb9 73 self.MacroDict = {}\r
4234283c 74\r
b36d134f 75 ## GetFinalTargetSuffixMap() method\r
4234283c
LG
76 #\r
77 # Get final build target list\r
b36d134f 78 def GetFinalTargetSuffixMap(self):\r
4234283c
LG
79 if not self.InfModule or not self.CurrentArch:\r
80 return []\r
b36d134f
LG
81 if not self.FinalTargetSuffixMap:\r
82 FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)\r
83 for File in FinalBuildTargetList:\r
84 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)\r
85\r
86 # Check if current INF module has DEPEX\r
87 if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \\r
88 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:\r
89 ModuleType = self.InfModule.ModuleType\r
90 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
91\r
92 if ModuleType != DataType.SUP_MODULE_USER_DEFINED:\r
93 for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():\r
94 if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:\r
95 self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]\r
96\r
97 StrModule = str(self.InfModule)\r
98 PlatformModule = None\r
99 if StrModule in PlatformDataBase.Modules:\r
100 PlatformModule = PlatformDataBase.Modules[StrModule]\r
101 for LibraryClass in PlatformModule.LibraryClasses:\r
102 if LibraryClass.startswith("NULL"):\r
103 self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
104\r
105 DependencyList = [self.InfModule]\r
106 LibraryInstance = {}\r
107 DepexList = []\r
108 while len(DependencyList) > 0:\r
109 Module = DependencyList.pop(0)\r
110 if not Module:\r
111 continue\r
112 for Dep in Module.Depex[self.CurrentArch, ModuleType]:\r
113 if DepexList != []:\r
114 DepexList.append('AND')\r
115 DepexList.append('(')\r
116 DepexList.extend(Dep)\r
117 if DepexList[-1] == 'END': # no need of a END at this time\r
118 DepexList.pop()\r
119 DepexList.append(')')\r
120 if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
121 break\r
122 for LibName in Module.LibraryClasses:\r
123 if LibName in LibraryInstance:\r
124 continue\r
125 if PlatformModule and LibName in PlatformModule.LibraryClasses:\r
126 LibraryPath = PlatformModule.LibraryClasses[LibName]\r
127 else:\r
128 LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType]\r
129 if not LibraryPath:\r
130 LibraryPath = Module.LibraryClasses[LibName]\r
131 if not LibraryPath:\r
132 continue\r
133 LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
134 LibraryInstance[LibName] = LibraryModule\r
135 DependencyList.append(LibraryModule)\r
136 if DepexList:\r
137 Dpx = DependencyExpression(DepexList, ModuleType, True)\r
138 if len(Dpx.PostfixNotation) != 0:\r
139 # It means this module has DEPEX\r
140 self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex']\r
141 return self.FinalTargetSuffixMap\r
4234283c 142\r
30fdf114
LG
143 ## __InfParse() method\r
144 #\r
145 # Parse inf file to get module information\r
146 #\r
147 # @param self The object pointer\r
148 # @param Dict dictionary contains macro and value pair\r
149 #\r
150 def __InfParse__(self, Dict = {}):\r
151\r
152 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
153\r
154 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
97fa0ee9
YL
155 if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':\r
156 pass\r
157 elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
30fdf114
LG
158 self.InfFileName = self.InfFileName[1:]\r
159\r
160 if self.InfFileName.find('$') == -1:\r
161 InfPath = NormPath(self.InfFileName)\r
162 if not os.path.exists(InfPath):\r
163 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)\r
164 if not os.path.exists(InfPath):\r
165 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))\r
166\r
167 self.CurrentArch = self.GetCurrentArch()\r
168 #\r
169 # Get the InfClass object\r
170 #\r
171\r
172 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
e56468c0 173 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
30fdf114
LG
174 if ErrorCode != 0:\r
175 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
97fa0ee9
YL
176\r
177 if self.OverrideGuid:\r
178 PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
30fdf114
LG
179 if self.CurrentArch != None:\r
180\r
0d2711a6 181 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
182 #\r
183 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath\r
184 #\r
185 self.BaseName = Inf.BaseName\r
186 self.ModuleGuid = Inf.Guid\r
187 self.ModuleType = Inf.ModuleType\r
52302d4d 188 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
b303ea72 189 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
30fdf114
LG
190 if Inf.AutoGenVersion < 0x00010005:\r
191 self.ModuleType = Inf.ComponentType\r
192 self.VersionString = Inf.Version\r
193 self.BinFileList = Inf.Binaries\r
194 self.SourceFileList = Inf.Sources\r
195 if self.KeepReloc == None and Inf.Shadow:\r
196 self.ShadowFromInfFile = Inf.Shadow\r
197\r
198 else:\r
0d2711a6 199 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
200 self.BaseName = Inf.BaseName\r
201 self.ModuleGuid = Inf.Guid\r
202 self.ModuleType = Inf.ModuleType\r
52302d4d 203 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
b303ea72 204 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
30fdf114
LG
205 self.VersionString = Inf.Version\r
206 self.BinFileList = Inf.Binaries\r
207 self.SourceFileList = Inf.Sources\r
208 if self.BinFileList == []:\r
209 EdkLogger.error("GenFds", GENFDS_ERROR,\r
210 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
211 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
212\r
97fa0ee9
YL
213 if self.OverrideGuid:\r
214 self.ModuleGuid = self.OverrideGuid\r
215\r
30fdf114
LG
216 if len(self.SourceFileList) != 0 and not self.InDsc:\r
217 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
218\r
da92f276 219 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
220 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) \r
221\r
30fdf114
LG
222 if Inf._Defs != None and len(Inf._Defs) > 0:\r
223 self.OptRomDefs.update(Inf._Defs)\r
2bc3256c 224\r
e8a47801
LG
225 self.PatchPcds = []\r
226 InfPcds = Inf.Pcds\r
227 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
228 FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
2bc3256c
LG
229\r
230 # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
231 # But INF file path in FDF and DSC file may have real case characters.\r
232 # Try to convert the path to lower case to see if PCDs value are override by DSC.\r
e8a47801
LG
233 DscModules = {}\r
234 for DscModule in Platform.Modules:\r
235 DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]\r
236 for PcdKey in InfPcds:\r
237 Pcd = InfPcds[PcdKey]\r
238 if not hasattr(Pcd, 'Offset'):\r
239 continue\r
240 if Pcd.Type != 'PatchableInModule':\r
241 continue\r
2bc3256c 242 # Override Patchable PCD value by the value from DSC\r
e8a47801
LG
243 PatchPcd = None\r
244 InfLowerPath = str(PathClassObj).lower()\r
245 if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
246 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
247 elif PcdKey in Platform.Pcds:\r
248 PatchPcd = Platform.Pcds[PcdKey]\r
249 DscOverride = False\r
250 if PatchPcd and Pcd.Type == PatchPcd.Type:\r
251 DefaultValue = PatchPcd.DefaultValue\r
252 DscOverride = True\r
2bc3256c
LG
253\r
254 # Override Patchable PCD value by the value from FDF\r
e8a47801
LG
255 FdfOverride = False\r
256 if PcdKey in FdfPcdDict:\r
257 DefaultValue = FdfPcdDict[PcdKey]\r
258 FdfOverride = True\r
2bc3256c 259\r
e8a47801
LG
260 if not DscOverride and not FdfOverride:\r
261 continue\r
2bc3256c 262 # Check value, if value are equal, no need to patch\r
e8a47801
LG
263 if Pcd.DatumType == "VOID*":\r
264 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
265 continue\r
2bc3256c 266 # Get the string size from FDF or DSC\r
e8a47801 267 if DefaultValue[0] == 'L':\r
2bc3256c 268 # Remove L"", but the '\0' must be appended\r
e8a47801
LG
269 MaxDatumSize = str((len(DefaultValue) - 2) * 2)\r
270 elif DefaultValue[0] == '{':\r
271 MaxDatumSize = str(len(DefaultValue.split(',')))\r
272 else:\r
273 MaxDatumSize = str(len(DefaultValue) - 1)\r
274 if DscOverride:\r
275 Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
2bc3256c 276 # If no defined the maximum size in DSC, try to get current size from INF\r
e8a47801
LG
277 if Pcd.MaxDatumSize in ['', None]:\r
278 Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))\r
279 else:\r
280 Base1 = Base2 = 10\r
281 if Pcd.DefaultValue.upper().startswith('0X'):\r
282 Base1 = 16\r
283 if DefaultValue.upper().startswith('0X'):\r
284 Base2 = 16\r
285 try:\r
286 PcdValueInImg = int(Pcd.DefaultValue, Base1)\r
287 PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
288 if PcdValueInImg == PcdValueInDscOrFdf:\r
289 continue\r
290 except:\r
291 continue\r
2bc3256c 292 # Check the Pcd size and data type\r
e8a47801
LG
293 if Pcd.DatumType == "VOID*":\r
294 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
295 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
296 % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
297 else:\r
298 if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \\r
299 or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:\r
300 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
301 % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
97fa0ee9
YL
302 self.PatchPcds.append((Pcd, DefaultValue))\r
303\r
4234283c 304 self.InfModule = Inf\r
e8a47801
LG
305 self.PcdIsDriver = Inf.PcdIsDriver\r
306 self.IsBinaryModule = Inf.IsBinaryModule\r
307 GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)\r
308 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)\r
309 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)\r
310 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)\r
311 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)\r
30fdf114
LG
312\r
313 #\r
314 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\\r
315 #\r
316\r
317 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \\r
318 self.ModuleGuid + self.BaseName)\r
319 if not os.path.exists(self.OutputPath) :\r
320 os.makedirs(self.OutputPath)\r
321\r
322 self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
323 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
324\r
97fa0ee9 325 ## PatchEfiFile\r
e8a47801
LG
326 #\r
327 # Patch EFI file with patch PCD\r
328 #\r
329 # @param EfiFile: EFI file needs to be patched.\r
330 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name\r
331 # If passed in file does not end with efi, return as is\r
332 #\r
97fa0ee9 333 def PatchEfiFile(self, EfiFile, FileType):\r
b21a13fb
YZ
334 #\r
335 # If the module does not have any patches, then return path to input file\r
336 # \r
e8a47801
LG
337 if not self.PatchPcds:\r
338 return EfiFile\r
b21a13fb
YZ
339\r
340 #\r
341 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED\r
342 # \r
97fa0ee9
YL
343 if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":\r
344 return EfiFile\r
b21a13fb
YZ
345\r
346 #\r
347 # Generate path to patched output file\r
348 #\r
349 Basename = os.path.basename(EfiFile)\r
350 Output = os.path.normpath (os.path.join(self.OutputPath, Basename))\r
351\r
352 #\r
353 # If this file has already been patched, then return the path to the patched file\r
354 #\r
355 if self.PatchedBinFile == Output:\r
356 return Output\r
357\r
358 #\r
359 # If a different file from the same module has already been patched, then generate an error\r
360 # \r
97fa0ee9
YL
361 if self.PatchedBinFile:\r
362 EdkLogger.error("GenFds", GENFDS_ERROR,\r
363 'Only one binary file can be patched:\n'\r
364 ' a binary file has been patched: %s\n'\r
365 ' current file: %s' % (self.PatchedBinFile, EfiFile),\r
366 File=self.InfFileName)\r
b21a13fb
YZ
367\r
368 #\r
369 # Copy unpatched file contents to output file location to perform patching\r
370 # \r
1be2ed90 371 CopyLongFilePath(EfiFile, Output)\r
b21a13fb
YZ
372\r
373 #\r
374 # Apply patches to patched output file\r
375 # \r
97fa0ee9
YL
376 for Pcd, Value in self.PatchPcds:\r
377 RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)\r
e8a47801
LG
378 if RetVal:\r
379 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
b21a13fb
YZ
380\r
381 #\r
382 # Save the path of the patched output file\r
383 # \r
384 self.PatchedBinFile = Output\r
385\r
386 #\r
387 # Return path to patched output file\r
388 # \r
e8a47801 389 return Output\r
b21a13fb 390\r
30fdf114
LG
391 ## GenFfs() method\r
392 #\r
393 # Generate FFS\r
394 #\r
52302d4d
LG
395 # @param self The object pointer\r
396 # @param Dict dictionary contains macro and value pair\r
397 # @param FvChildAddr Array of the inside FvImage base address\r
398 # @param FvParentAddr Parent Fv base address\r
399 # @retval string Generated FFS file name\r
30fdf114 400 #\r
52302d4d 401 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):\r
30fdf114
LG
402 #\r
403 # Parse Inf file get Module related information\r
404 #\r
405\r
406 self.__InfParse__(Dict)\r
05cc51ad 407 SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\r
0acb3d28 408 DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
6780eef1 409 \r
0acb3d28
AC
410 SrcFileDir = "."\r
411 SrcPath = os.path.dirname(SrcFile)\r
412 SrcFileName = os.path.basename(SrcFile)\r
413 SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName) \r
414 DestPath = os.path.dirname(DestFile)\r
415 DestFileName = os.path.basename(DestFile)\r
416 DestFileBase, DestFileExt = os.path.splitext(DestFileName) \r
417 self.MacroDict = {\r
418 # source file\r
419 "${src}" : SrcFile,\r
420 "${s_path}" : SrcPath,\r
421 "${s_dir}" : SrcFileDir,\r
422 "${s_name}" : SrcFileName,\r
423 "${s_base}" : SrcFileBase,\r
424 "${s_ext}" : SrcFileExt,\r
425 # destination file\r
426 "${dst}" : DestFile,\r
427 "${d_path}" : DestPath,\r
428 "${d_name}" : DestFileName,\r
429 "${d_base}" : DestFileBase,\r
430 "${d_ext}" : DestFileExt\r
431 }\r
6780eef1
LG
432 #\r
433 # Allow binary type module not specify override rule in FDF file.\r
434 # \r
97fa0ee9 435 if len(self.BinFileList) > 0:\r
6780eef1
LG
436 if self.Rule == None or self.Rule == "":\r
437 self.Rule = "BINARY"\r
438 \r
30fdf114
LG
439 #\r
440 # Get the rule of how to generate Ffs file\r
441 #\r
442 Rule = self.__GetRule__()\r
443 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)\r
b303ea72
LG
444 #\r
445 # Convert Fv File Type for PI1.1 SMM driver.\r
446 #\r
da92f276 447 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
448 if Rule.FvFileType == 'DRIVER':\r
449 Rule.FvFileType = 'SMM'\r
450 #\r
451 # Framework SMM Driver has no SMM FV file type\r
452 #\r
da92f276 453 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
454 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':\r
455 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)\r
30fdf114
LG
456 #\r
457 # For the rule only has simpleFile\r
458 #\r
459 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :\r
460 SectionOutputList = self.__GenSimpleFileSection__(Rule)\r
461 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)\r
462 return FfsOutput\r
463 #\r
464 # For Rule has ComplexFile\r
465 #\r
466 elif isinstance(Rule, RuleComplexFile.RuleComplexFile):\r
52302d4d 467 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)\r
30fdf114
LG
468 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)\r
469\r
470 return FfsOutput\r
471\r
472 ## __ExtendMacro__() method\r
473 #\r
474 # Replace macro with its value\r
475 #\r
476 # @param self The object pointer\r
477 # @param String The string to be replaced\r
478 # @retval string Macro replaced string\r
479 #\r
480 def __ExtendMacro__ (self, String):\r
481 MacroDict = {\r
482 '$(INF_OUTPUT)' : self.EfiOutputPath,\r
483 '$(MODULE_NAME)' : self.BaseName,\r
484 '$(BUILD_NUMBER)': self.BuildNum,\r
485 '$(INF_VERSION)' : self.VersionString,\r
486 '$(NAMED_GUID)' : self.ModuleGuid\r
487 }\r
488 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)\r
0acb3d28 489 String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) \r
30fdf114
LG
490 return String\r
491\r
492 ## __GetRule__() method\r
493 #\r
494 # Get correct rule for generating FFS for this INF\r
495 #\r
496 # @param self The object pointer\r
497 # @retval Rule Rule object\r
498 #\r
499 def __GetRule__ (self) :\r
500 CurrentArchList = []\r
501 if self.CurrentArch == None:\r
502 CurrentArchList = ['common']\r
503 else:\r
504 CurrentArchList.append(self.CurrentArch)\r
505\r
506 for CurrentArch in CurrentArchList:\r
507 RuleName = 'RULE' + \\r
508 '.' + \\r
509 CurrentArch.upper() + \\r
510 '.' + \\r
511 self.ModuleType.upper()\r
512 if self.Rule != None:\r
513 RuleName = RuleName + \\r
514 '.' + \\r
515 self.Rule.upper()\r
516\r
517 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
518 if Rule != None:\r
519 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
520 return Rule\r
521\r
522 RuleName = 'RULE' + \\r
523 '.' + \\r
524 'COMMON' + \\r
525 '.' + \\r
526 self.ModuleType.upper()\r
527\r
528 if self.Rule != None:\r
529 RuleName = RuleName + \\r
530 '.' + \\r
531 self.Rule.upper()\r
532\r
533 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))\r
534\r
535 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
536 if Rule != None:\r
537 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
538 return Rule\r
539\r
540 if Rule == None :\r
541 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \\r
542 % (RuleName, self.InfFileName))\r
543\r
544 ## __GetPlatformArchList__() method\r
545 #\r
546 # Get Arch list this INF built under\r
547 #\r
548 # @param self The object pointer\r
549 # @retval list Arch list\r
550 #\r
551 def __GetPlatformArchList__(self):\r
552\r
05cc51ad 553 InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
30fdf114 554 DscArchList = []\r
0d2711a6 555 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
556 if PlatformDataBase != None:\r
557 if InfFileKey in PlatformDataBase.Modules:\r
558 DscArchList.append ('IA32')\r
559\r
0d2711a6 560 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
561 if PlatformDataBase != None:\r
562 if InfFileKey in PlatformDataBase.Modules:\r
563 DscArchList.append ('X64')\r
564\r
0d2711a6 565 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
566 if PlatformDataBase != None:\r
567 if InfFileKey in (PlatformDataBase.Modules):\r
568 DscArchList.append ('IPF')\r
569\r
0d2711a6 570 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
571 if PlatformDataBase != None:\r
572 if InfFileKey in (PlatformDataBase.Modules):\r
573 DscArchList.append ('ARM')\r
574\r
0d2711a6 575 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
576 if PlatformDataBase != None:\r
577 if InfFileKey in (PlatformDataBase.Modules):\r
578 DscArchList.append ('EBC')\r
579\r
4afd3d04
LG
580 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'AARCH64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
581 if PlatformDataBase != None:\r
582 if InfFileKey in (PlatformDataBase.Modules):\r
583 DscArchList.append ('AARCH64')\r
584\r
30fdf114
LG
585 return DscArchList\r
586\r
587 ## GetCurrentArch() method\r
588 #\r
589 # Get Arch list of the module from this INF is to be placed into flash\r
590 #\r
591 # @param self The object pointer\r
592 # @retval list Arch list\r
593 #\r
594 def GetCurrentArch(self) :\r
595\r
596 TargetArchList = GenFdsGlobalVariable.ArchList\r
597\r
598 PlatformArchList = self.__GetPlatformArchList__()\r
599\r
600 CurArchList = TargetArchList\r
601 if PlatformArchList != []:\r
602 CurArchList = list(set (TargetArchList) & set (PlatformArchList))\r
603 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))\r
604\r
605 ArchList = []\r
606 if self.KeyStringList != []:\r
607 for Key in self.KeyStringList:\r
608 Key = GenFdsGlobalVariable.MacroExtend(Key)\r
609 Target, Tag, Arch = Key.split('_')\r
610 if Arch in CurArchList:\r
611 ArchList.append(Arch)\r
612 if Target not in self.TargetOverrideList:\r
613 self.TargetOverrideList.append(Target)\r
614 else:\r
615 ArchList = CurArchList\r
616\r
617 UseArchList = TargetArchList\r
618 if self.UseArch != None:\r
619 UseArchList = []\r
620 UseArchList.append(self.UseArch)\r
621 ArchList = list(set (UseArchList) & set (ArchList))\r
622\r
623 self.InfFileName = NormPath(self.InfFileName)\r
624 if len(PlatformArchList) == 0:\r
625 self.InDsc = False\r
626 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
e56468c0 627 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
30fdf114
LG
628 if ErrorCode != 0:\r
629 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
630 if len(ArchList) == 1:\r
631 Arch = ArchList[0]\r
632 return Arch\r
633 elif len(ArchList) > 1:\r
634 if len(PlatformArchList) == 0:\r
635 EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName))\r
636 else:\r
637 EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName))\r
638 else:\r
639 EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \\r
640 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))\r
641\r
642 ## __GetEFIOutPutPath__() method\r
643 #\r
644 # Get the output path for generated files\r
645 #\r
646 # @param self The object pointer\r
647 # @retval string Path that output files from this INF go to\r
648 #\r
649 def __GetEFIOutPutPath__(self):\r
650 Arch = ''\r
651 OutputPath = ''\r
652 (ModulePath, FileName) = os.path.split(self.InfFileName)\r
79b74a03 653 Index = FileName.rfind('.')\r
30fdf114 654 FileName = FileName[0:Index]\r
97fa0ee9
YL
655 if self.OverrideGuid:\r
656 FileName = self.OverrideGuid\r
30fdf114
LG
657 Arch = "NoneArch"\r
658 if self.CurrentArch != None:\r
659 Arch = self.CurrentArch\r
660\r
661 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
662 Arch ,\r
663 ModulePath,\r
664 FileName,\r
665 'OUTPUT'\r
666 )\r
667 OutputPath = os.path.realpath(OutputPath)\r
668 return OutputPath\r
669\r
670 ## __GenSimpleFileSection__() method\r
671 #\r
672 # Generate section by specified file name or a list of files with file extension\r
673 #\r
674 # @param self The object pointer\r
675 # @param Rule The rule object used to generate section\r
676 # @retval string File name of the generated section file\r
677 #\r
678 def __GenSimpleFileSection__(self, Rule):\r
679 #\r
680 # Prepare the parameter of GenSection\r
681 #\r
682 FileList = []\r
683 OutputFileList = []\r
52302d4d 684 GenSecInputFile = None\r
30fdf114
LG
685 if Rule.FileName != None:\r
686 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
da92f276
LG
687 if os.path.isabs(GenSecInputFile):\r
688 GenSecInputFile = os.path.normpath(GenSecInputFile)\r
689 else:\r
52302d4d 690 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))\r
30fdf114
LG
691 else:\r
692 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)\r
693\r
694 Index = 1\r
b303ea72
LG
695 SectionType = Rule.SectionType\r
696 #\r
697 # Convert Fv Section Type for PI1.1 SMM driver.\r
698 #\r
da92f276 699 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
700 if SectionType == 'DXE_DEPEX':\r
701 SectionType = 'SMM_DEPEX'\r
702 #\r
703 # Framework SMM Driver has no SMM_DEPEX section type\r
704 #\r
da92f276 705 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
706 if SectionType == 'SMM_DEPEX':\r
707 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
30fdf114
LG
708 NoStrip = True\r
709 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
710 if self.KeepReloc != None:\r
711 NoStrip = self.KeepReloc\r
712 elif Rule.KeepReloc != None:\r
713 NoStrip = Rule.KeepReloc\r
714 elif self.ShadowFromInfFile != None:\r
715 NoStrip = self.ShadowFromInfFile\r
716\r
717 if FileList != [] :\r
718 for File in FileList:\r
719\r
720 SecNum = '%d' %Index\r
721 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
722 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
723 Index = Index + 1\r
724 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
52302d4d
LG
725 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)\r
726\r
727 #Get PE Section alignment when align is set to AUTO\r
728 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
729 ImageObj = PeImageClass (File)\r
730 if ImageObj.SectionAlignment < 0x400:\r
731 self.Alignment = str (ImageObj.SectionAlignment)\r
732 else:\r
733 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
30fdf114
LG
734\r
735 if not NoStrip:\r
736 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
737 if not os.path.exists(FileBeforeStrip) or \\r
1be2ed90
HC
738 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
739 CopyLongFilePath(File, FileBeforeStrip)\r
30fdf114
LG
740 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
741 GenFdsGlobalVariable.GenerateFirmwareImage(\r
742 StrippedFile,\r
52302d4d 743 [File],\r
30fdf114
LG
744 Strip=True\r
745 )\r
746 File = StrippedFile\r
747\r
748 if SectionType == 'TE':\r
749 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
750 GenFdsGlobalVariable.GenerateFirmwareImage(\r
751 TeFile,\r
52302d4d 752 [File],\r
30fdf114
LG
753 Type='te'\r
754 )\r
755 File = TeFile\r
756\r
757 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])\r
758 OutputFileList.append(OutputFile)\r
759 else:\r
760 SecNum = '%d' %Index\r
761 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
762 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
763 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
52302d4d
LG
764 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)\r
765\r
766 #Get PE Section alignment when align is set to AUTO\r
767 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
768 ImageObj = PeImageClass (GenSecInputFile)\r
769 if ImageObj.SectionAlignment < 0x400:\r
770 self.Alignment = str (ImageObj.SectionAlignment)\r
771 else:\r
772 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
30fdf114
LG
773\r
774 if not NoStrip:\r
775 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
776 if not os.path.exists(FileBeforeStrip) or \\r
1be2ed90
HC
777 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
778 CopyLongFilePath(GenSecInputFile, FileBeforeStrip)\r
779\r
30fdf114
LG
780 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
781 GenFdsGlobalVariable.GenerateFirmwareImage(\r
782 StrippedFile,\r
52302d4d 783 [GenSecInputFile],\r
30fdf114
LG
784 Strip=True\r
785 )\r
786 GenSecInputFile = StrippedFile\r
787\r
788 if SectionType == 'TE':\r
789 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
790 GenFdsGlobalVariable.GenerateFirmwareImage(\r
791 TeFile,\r
52302d4d 792 [GenSecInputFile],\r
30fdf114
LG
793 Type='te'\r
794 )\r
795 GenSecInputFile = TeFile\r
796\r
797 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])\r
798 OutputFileList.append(OutputFile)\r
799\r
800 return OutputFileList\r
801\r
802 ## __GenSimpleFileFfs__() method\r
803 #\r
804 # Generate FFS\r
805 #\r
806 # @param self The object pointer\r
807 # @param Rule The rule object used to generate section\r
808 # @param InputFileList The output file list from GenSection\r
809 # @retval string Generated FFS file name\r
810 #\r
811 def __GenSimpleFileFfs__(self, Rule, InputFileList):\r
812 FfsOutput = self.OutputPath + \\r
813 os.sep + \\r
814 self.__ExtendMacro__(Rule.NameGuid) + \\r
815 '.ffs'\r
816\r
817 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))\r
818 InputSection = []\r
819 SectionAlignments = []\r
820 for InputFile in InputFileList:\r
821 InputSection.append(InputFile)\r
52302d4d 822 SectionAlignments.append(Rule.SectAlignment)\r
30fdf114
LG
823\r
824 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
825 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
826 if len(PcdValue) == 0:\r
827 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
828 % (Rule.NameGuid))\r
829 if PcdValue.startswith('{'):\r
830 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
831 RegistryGuidStr = PcdValue\r
832 if len(RegistryGuidStr) == 0:\r
833 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
834 % (Rule.NameGuid))\r
835 self.ModuleGuid = RegistryGuidStr\r
836\r
837 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,\r
838 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
839 self.ModuleGuid, Fixed=Rule.Fixed,\r
840 CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
841 SectionAlign=SectionAlignments\r
842 )\r
843 return FfsOutput\r
844\r
845 ## __GenComplexFileSection__() method\r
846 #\r
847 # Generate section by sections in Rule\r
848 #\r
52302d4d
LG
849 # @param self The object pointer\r
850 # @param Rule The rule object used to generate section\r
851 # @param FvChildAddr Array of the inside FvImage base address\r
852 # @param FvParentAddr Parent Fv base address\r
853 # @retval string File name of the generated section file\r
30fdf114 854 #\r
52302d4d 855 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):\r
30fdf114
LG
856 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
857 if Rule.KeepReloc != None:\r
858 self.KeepRelocFromRule = Rule.KeepReloc\r
859 SectFiles = []\r
860 SectAlignments = []\r
861 Index = 1\r
da92f276 862 HasGneratedFlag = False\r
e8a47801
LG
863 if self.PcdIsDriver == 'PEI_PCD_DRIVER':\r
864 if self.IsBinaryModule:\r
865 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")\r
866 else:\r
867 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")\r
868 PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")\r
869 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
870 [PcdExDbFileName],\r
871 "EFI_SECTION_RAW",\r
872 )\r
873 SectFiles.append(PcdExDbSecName)\r
874 SectAlignments.append(None)\r
875 elif self.PcdIsDriver == 'DXE_PCD_DRIVER':\r
876 if self.IsBinaryModule:\r
877 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")\r
878 else:\r
879 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")\r
880 PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")\r
881 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
882 [PcdExDbFileName],\r
883 "EFI_SECTION_RAW",\r
884 )\r
885 SectFiles.append(PcdExDbSecName)\r
886 SectAlignments.append(None)\r
30fdf114
LG
887 for Sect in Rule.SectionList:\r
888 SecIndex = '%d' %Index\r
889 SectList = []\r
b303ea72
LG
890 #\r
891 # Convert Fv Section Type for PI1.1 SMM driver.\r
892 #\r
da92f276 893 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
894 if Sect.SectionType == 'DXE_DEPEX':\r
895 Sect.SectionType = 'SMM_DEPEX'\r
896 #\r
897 # Framework SMM Driver has no SMM_DEPEX section type\r
898 #\r
da92f276 899 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
900 if Sect.SectionType == 'SMM_DEPEX':\r
901 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
52302d4d
LG
902 #\r
903 # process the inside FvImage from FvSection or GuidSection\r
904 #\r
905 if FvChildAddr != []:\r
906 if isinstance(Sect, FvImageSection):\r
907 Sect.FvAddr = FvChildAddr.pop(0)\r
908 elif isinstance(Sect, GuidSection):\r
909 Sect.FvAddr = FvChildAddr\r
910 if FvParentAddr != None and isinstance(Sect, GuidSection):\r
911 Sect.FvParentAddr = FvParentAddr\r
912 \r
30fdf114
LG
913 if Rule.KeyStringList != []:\r
914 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)\r
915 else :\r
916 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)\r
da92f276
LG
917 \r
918 if not HasGneratedFlag:\r
919 UniVfrOffsetFileSection = "" \r
05cc51ad 920 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
da92f276
LG
921 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]\r
922 #\r
923 # Search the source list in InfData to find if there are .vfr file exist.\r
924 #\r
925 VfrUniBaseName = {}\r
926 VfrUniOffsetList = []\r
927 for SourceFile in InfData.Sources:\r
928 if SourceFile.Type.upper() == ".VFR" :\r
929 #\r
930 # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
931 #\r
932 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
933 if SourceFile.Type.upper() == ".UNI" :\r
934 #\r
935 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
936 #\r
937 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")\r
938 \r
939 \r
940 if len(VfrUniBaseName) > 0:\r
941 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)\r
942 #\r
943 # Generate the Raw data of raw section\r
944 #\r
945 os.path.join( self.OutputPath, self.BaseName + '.offset')\r
946 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset')\r
947 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
948 \r
949 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
950 \r
951 UniVfrOffsetFileNameList = []\r
952 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
953 """Call GenSection"""\r
954 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
955 UniVfrOffsetFileNameList,\r
956 "EFI_SECTION_RAW"\r
957 )\r
958 os.remove(UniVfrOffsetFileName) \r
959 SectList.append(UniVfrOffsetFileSection)\r
960 HasGneratedFlag = True\r
961 \r
30fdf114
LG
962 for SecName in SectList :\r
963 SectFiles.append(SecName)\r
964 SectAlignments.append(Align)\r
965 Index = Index + 1\r
966 return SectFiles, SectAlignments\r
967\r
968 ## __GenComplexFileFfs__() method\r
969 #\r
970 # Generate FFS\r
971 #\r
972 # @param self The object pointer\r
973 # @param Rule The rule object used to generate section\r
974 # @param InputFileList The output file list from GenSection\r
975 # @retval string Generated FFS file name\r
976 #\r
977 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):\r
978\r
979 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
980 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
981 if len(PcdValue) == 0:\r
982 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
983 % (Rule.NameGuid))\r
984 if PcdValue.startswith('{'):\r
985 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
986 RegistryGuidStr = PcdValue\r
987 if len(RegistryGuidStr) == 0:\r
988 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
989 % (Rule.NameGuid))\r
990 self.ModuleGuid = RegistryGuidStr\r
991\r
992 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
993 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,\r
994 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
995 self.ModuleGuid, Fixed=Rule.Fixed,\r
996 CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
997 SectionAlign=Alignments\r
998 )\r
999 return FfsOutput\r
1000\r
1001 ## __GetGenFfsCmdParameter__() method\r
1002 #\r
1003 # Create parameter string for GenFfs\r
1004 #\r
1005 # @param self The object pointer\r
1006 # @param Rule The rule object used to generate section\r
1007 # @retval tuple (FileType, Fixed, CheckSum, Alignment)\r
1008 #\r
1009 def __GetGenFfsCmdParameter__(self, Rule):\r
1010 result = tuple()\r
1011 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])\r
1012 if Rule.Fixed != False:\r
1013 result += ('-x',)\r
1014 if Rule.CheckSum != False:\r
1015 result += ('-s',)\r
1016\r
1017 if Rule.Alignment != None and Rule.Alignment != '':\r
1018 result += ('-a', Rule.Alignment)\r
1019\r
1020 return result\r
da92f276
LG
1021 \r
1022 ## __GetBuildOutputMapFileVfrUniInfo() method\r
1023 #\r
1024 # Find the offset of UNI/INF object offset in the EFI image file.\r
1025 #\r
1026 # @param self The object pointer\r
1027 # @param VfrUniBaseName A name list contain the UNI/INF object name.\r
1028 # @retval RetValue A list contain offset of UNI/INF object.\r
1029 # \r
1030 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
da92f276 1031 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
22a99b87
YL
1032 EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")\r
1033 return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
da92f276
LG
1034 \r
1035 ## __GenUniVfrOffsetFile() method\r
1036 #\r
1037 # Generate the offset file for the module which contain VFR or UNI file.\r
1038 #\r
1039 # @param self The object pointer\r
1040 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.\r
1041 # @param UniVfrOffsetFileName The output offset file name.\r
1042 #\r
1043 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):\r
1044 \r
1045 try:\r
1046 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
1047 except:\r
1048 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)\r
1049 \r
1050 # Use a instance of StringIO to cache data\r
1051 fStringIO = StringIO.StringIO('') \r
1052 \r
1053 for Item in VfrUniOffsetList:\r
1054 if (Item[0].find("Strings") != -1):\r
1055 #\r
1056 # UNI offset in image.\r
1057 # GUID + Offset\r
1058 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
1059 #\r
1060 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
1061 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
1062 fStringIO.write(''.join(UniGuid)) \r
1063 UniValue = pack ('Q', int (Item[1], 16))\r
1064 fStringIO.write (UniValue)\r
1065 else:\r
1066 #\r
1067 # VFR binary offset in image.\r
1068 # GUID + Offset\r
1069 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
1070 #\r
1071 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
1072 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
1073 fStringIO.write(''.join(VfrGuid)) \r
1074 type (Item[1]) \r
1075 VfrValue = pack ('Q', int (Item[1], 16))\r
1076 fStringIO.write (VfrValue)\r
1077 \r
1078 #\r
1079 # write data into file.\r
1080 #\r
1081 try : \r
1082 fInputfile.write (fStringIO.getvalue())\r
1083 except:\r
1084 EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None)\r
1085 \r
1086 fStringIO.close ()\r
1087 fInputfile.close ()\r
1088 \r
1089 \r
1090 \r
1091 \r
1092 \r
1093 \r
1094 \r
1095 \r