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