]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsInfStatement.py
Sync EDKII BaseTools to BaseTools project r1971
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
1 ## @file
2 # process FFS generation from INF statement
3 #
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Rule
19 import os
20 import shutil
21 from GenFdsGlobalVariable import GenFdsGlobalVariable
22 import Ffs
23 import subprocess
24 import sys
25 import Section
26 import RuleSimpleFile
27 import RuleComplexFile
28 from CommonDataClass.FdfClass import FfsInfStatementClassObject
29 from Common.String import *
30 from Common.Misc import PathClass
31 from Common.Misc import GuidStructureByteArrayToGuidString
32 from Common import EdkLogger
33 from Common.BuildToolError import *
34 from GuidSection import GuidSection
35 from FvImageSection import FvImageSection
36 from Common.Misc import PeImageClass
37
38 ## generate FFS from INF
39 #
40 #
41 class FfsInfStatement(FfsInfStatementClassObject):
42 ## The constructor
43 #
44 # @param self The object pointer
45 #
46 def __init__(self):
47 FfsInfStatementClassObject.__init__(self)
48 self.TargetOverrideList = []
49 self.ShadowFromInfFile = None
50 self.KeepRelocFromRule = None
51 self.InDsc = True
52 self.OptRomDefs = {}
53 self.PiSpecVersion = 0
54
55 ## __InfParse() method
56 #
57 # Parse inf file to get module information
58 #
59 # @param self The object pointer
60 # @param Dict dictionary contains macro and value pair
61 #
62 def __InfParse__(self, Dict = {}):
63
64 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
65
66 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
67 if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
68 self.InfFileName = self.InfFileName[1:]
69
70 if self.InfFileName.find('$') == -1:
71 InfPath = NormPath(self.InfFileName)
72 if not os.path.exists(InfPath):
73 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
74 if not os.path.exists(InfPath):
75 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
76
77 self.CurrentArch = self.GetCurrentArch()
78 #
79 # Get the InfClass object
80 #
81
82 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
83 ErrorCode, ErrorInfo = PathClassObj.Validate()
84 if ErrorCode != 0:
85 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
86
87 if self.CurrentArch != None:
88
89 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]
90 #
91 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
92 #
93 self.BaseName = Inf.BaseName
94 self.ModuleGuid = Inf.Guid
95 self.ModuleType = Inf.ModuleType
96 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
97 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
98 if Inf.AutoGenVersion < 0x00010005:
99 self.ModuleType = Inf.ComponentType
100 self.VersionString = Inf.Version
101 self.BinFileList = Inf.Binaries
102 self.SourceFileList = Inf.Sources
103 if self.KeepReloc == None and Inf.Shadow:
104 self.ShadowFromInfFile = Inf.Shadow
105
106 else:
107 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']
108 self.BaseName = Inf.BaseName
109 self.ModuleGuid = Inf.Guid
110 self.ModuleType = Inf.ModuleType
111 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
112 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
113 self.VersionString = Inf.Version
114 self.BinFileList = Inf.Binaries
115 self.SourceFileList = Inf.Sources
116 if self.BinFileList == []:
117 EdkLogger.error("GenFds", GENFDS_ERROR,
118 "INF %s specified in FDF could not be found in build ARCH %s!" \
119 % (self.InfFileName, GenFdsGlobalVariable.ArchList))
120
121 if len(self.SourceFileList) != 0 and not self.InDsc:
122 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
123
124 if self.ModuleType == 'SMM_CORE' and self.PiSpecVersion < 0x0001000A:
125 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)
126
127 if Inf._Defs != None and len(Inf._Defs) > 0:
128 self.OptRomDefs.update(Inf._Defs)
129
130 GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)
131 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)
132 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)
133 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)
134 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName)
135
136 #
137 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
138 #
139
140 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
141 self.ModuleGuid + self.BaseName)
142 if not os.path.exists(self.OutputPath) :
143 os.makedirs(self.OutputPath)
144
145 self.EfiOutputPath = self.__GetEFIOutPutPath__()
146 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
147
148 ## GenFfs() method
149 #
150 # Generate FFS
151 #
152 # @param self The object pointer
153 # @param Dict dictionary contains macro and value pair
154 # @param FvChildAddr Array of the inside FvImage base address
155 # @param FvParentAddr Parent Fv base address
156 # @retval string Generated FFS file name
157 #
158 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
159 #
160 # Parse Inf file get Module related information
161 #
162
163 self.__InfParse__(Dict)
164 #
165 # Get the rule of how to generate Ffs file
166 #
167 Rule = self.__GetRule__()
168 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
169 #
170 # Convert Fv File Type for PI1.1 SMM driver.
171 #
172 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:
173 if Rule.FvFileType == 'DRIVER':
174 Rule.FvFileType = 'SMM'
175 #
176 # Framework SMM Driver has no SMM FV file type
177 #
178 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:
179 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
180 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
181 #
182 # For the rule only has simpleFile
183 #
184 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
185 SectionOutputList = self.__GenSimpleFileSection__(Rule)
186 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
187 return FfsOutput
188 #
189 # For Rule has ComplexFile
190 #
191 elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
192 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
193 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
194
195 return FfsOutput
196
197 ## __ExtendMacro__() method
198 #
199 # Replace macro with its value
200 #
201 # @param self The object pointer
202 # @param String The string to be replaced
203 # @retval string Macro replaced string
204 #
205 def __ExtendMacro__ (self, String):
206 MacroDict = {
207 '$(INF_OUTPUT)' : self.EfiOutputPath,
208 '$(MODULE_NAME)' : self.BaseName,
209 '$(BUILD_NUMBER)': self.BuildNum,
210 '$(INF_VERSION)' : self.VersionString,
211 '$(NAMED_GUID)' : self.ModuleGuid
212 }
213 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
214 return String
215
216 ## __GetRule__() method
217 #
218 # Get correct rule for generating FFS for this INF
219 #
220 # @param self The object pointer
221 # @retval Rule Rule object
222 #
223 def __GetRule__ (self) :
224 CurrentArchList = []
225 if self.CurrentArch == None:
226 CurrentArchList = ['common']
227 else:
228 CurrentArchList.append(self.CurrentArch)
229
230 for CurrentArch in CurrentArchList:
231 RuleName = 'RULE' + \
232 '.' + \
233 CurrentArch.upper() + \
234 '.' + \
235 self.ModuleType.upper()
236 if self.Rule != None:
237 RuleName = RuleName + \
238 '.' + \
239 self.Rule.upper()
240
241 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
242 if Rule != None:
243 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
244 return Rule
245
246 RuleName = 'RULE' + \
247 '.' + \
248 'COMMON' + \
249 '.' + \
250 self.ModuleType.upper()
251
252 if self.Rule != None:
253 RuleName = RuleName + \
254 '.' + \
255 self.Rule.upper()
256
257 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
258
259 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
260 if Rule != None:
261 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
262 return Rule
263
264 if Rule == None :
265 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
266 % (RuleName, self.InfFileName))
267
268 ## __GetPlatformArchList__() method
269 #
270 # Get Arch list this INF built under
271 #
272 # @param self The object pointer
273 # @retval list Arch list
274 #
275 def __GetPlatformArchList__(self):
276
277 InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
278 DscArchList = []
279 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']
280 if PlatformDataBase != None:
281 if InfFileKey in PlatformDataBase.Modules:
282 DscArchList.append ('IA32')
283
284 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']
285 if PlatformDataBase != None:
286 if InfFileKey in PlatformDataBase.Modules:
287 DscArchList.append ('X64')
288
289 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']
290 if PlatformDataBase != None:
291 if InfFileKey in (PlatformDataBase.Modules):
292 DscArchList.append ('IPF')
293
294 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']
295 if PlatformDataBase != None:
296 if InfFileKey in (PlatformDataBase.Modules):
297 DscArchList.append ('ARM')
298
299 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']
300 if PlatformDataBase != None:
301 if InfFileKey in (PlatformDataBase.Modules):
302 DscArchList.append ('EBC')
303
304 return DscArchList
305
306 ## GetCurrentArch() method
307 #
308 # Get Arch list of the module from this INF is to be placed into flash
309 #
310 # @param self The object pointer
311 # @retval list Arch list
312 #
313 def GetCurrentArch(self) :
314
315 TargetArchList = GenFdsGlobalVariable.ArchList
316
317 PlatformArchList = self.__GetPlatformArchList__()
318
319 CurArchList = TargetArchList
320 if PlatformArchList != []:
321 CurArchList = list(set (TargetArchList) & set (PlatformArchList))
322 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
323
324 ArchList = []
325 if self.KeyStringList != []:
326 for Key in self.KeyStringList:
327 Key = GenFdsGlobalVariable.MacroExtend(Key)
328 Target, Tag, Arch = Key.split('_')
329 if Arch in CurArchList:
330 ArchList.append(Arch)
331 if Target not in self.TargetOverrideList:
332 self.TargetOverrideList.append(Target)
333 else:
334 ArchList = CurArchList
335
336 UseArchList = TargetArchList
337 if self.UseArch != None:
338 UseArchList = []
339 UseArchList.append(self.UseArch)
340 ArchList = list(set (UseArchList) & set (ArchList))
341
342 self.InfFileName = NormPath(self.InfFileName)
343 if len(PlatformArchList) == 0:
344 self.InDsc = False
345 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
346 ErrorCode, ErrorInfo = PathClassObj.Validate()
347 if ErrorCode != 0:
348 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
349 if len(ArchList) == 1:
350 Arch = ArchList[0]
351 return Arch
352 elif len(ArchList) > 1:
353 if len(PlatformArchList) == 0:
354 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))
355 else:
356 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))
357 else:
358 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." \
359 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
360
361 ## __GetEFIOutPutPath__() method
362 #
363 # Get the output path for generated files
364 #
365 # @param self The object pointer
366 # @retval string Path that output files from this INF go to
367 #
368 def __GetEFIOutPutPath__(self):
369 Arch = ''
370 OutputPath = ''
371 (ModulePath, FileName) = os.path.split(self.InfFileName)
372 Index = FileName.find('.')
373 FileName = FileName[0:Index]
374 Arch = "NoneArch"
375 if self.CurrentArch != None:
376 Arch = self.CurrentArch
377
378 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
379 Arch ,
380 ModulePath,
381 FileName,
382 'OUTPUT'
383 )
384 OutputPath = os.path.realpath(OutputPath)
385 return OutputPath
386
387 ## __GenSimpleFileSection__() method
388 #
389 # Generate section by specified file name or a list of files with file extension
390 #
391 # @param self The object pointer
392 # @param Rule The rule object used to generate section
393 # @retval string File name of the generated section file
394 #
395 def __GenSimpleFileSection__(self, Rule):
396 #
397 # Prepare the parameter of GenSection
398 #
399 FileList = []
400 OutputFileList = []
401 GenSecInputFile = None
402 if Rule.FileName != None:
403 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
404 if os.path.isabs(GenSecInputFile):
405 GenSecInputFile = os.path.normpath(GenSecInputFile)
406 else:
407 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
408 else:
409 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
410
411 Index = 1
412 SectionType = Rule.SectionType
413 #
414 # Convert Fv Section Type for PI1.1 SMM driver.
415 #
416 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:
417 if SectionType == 'DXE_DEPEX':
418 SectionType = 'SMM_DEPEX'
419 #
420 # Framework SMM Driver has no SMM_DEPEX section type
421 #
422 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:
423 if SectionType == 'SMM_DEPEX':
424 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
425 NoStrip = True
426 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
427 if self.KeepReloc != None:
428 NoStrip = self.KeepReloc
429 elif Rule.KeepReloc != None:
430 NoStrip = Rule.KeepReloc
431 elif self.ShadowFromInfFile != None:
432 NoStrip = self.ShadowFromInfFile
433
434 if FileList != [] :
435 for File in FileList:
436
437 SecNum = '%d' %Index
438 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
439 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
440 Index = Index + 1
441 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
442 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
443
444 #Get PE Section alignment when align is set to AUTO
445 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
446 ImageObj = PeImageClass (File)
447 if ImageObj.SectionAlignment < 0x400:
448 self.Alignment = str (ImageObj.SectionAlignment)
449 else:
450 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
451
452 if not NoStrip:
453 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
454 if not os.path.exists(FileBeforeStrip) or \
455 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
456 shutil.copyfile(File, FileBeforeStrip)
457 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
458 GenFdsGlobalVariable.GenerateFirmwareImage(
459 StrippedFile,
460 [File],
461 Strip=True
462 )
463 File = StrippedFile
464
465 if SectionType == 'TE':
466 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
467 GenFdsGlobalVariable.GenerateFirmwareImage(
468 TeFile,
469 [File],
470 Type='te'
471 )
472 File = TeFile
473
474 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
475 OutputFileList.append(OutputFile)
476 else:
477 SecNum = '%d' %Index
478 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
479 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
480 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
481 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
482
483 #Get PE Section alignment when align is set to AUTO
484 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
485 ImageObj = PeImageClass (GenSecInputFile)
486 if ImageObj.SectionAlignment < 0x400:
487 self.Alignment = str (ImageObj.SectionAlignment)
488 else:
489 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
490
491 if not NoStrip:
492 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
493 if not os.path.exists(FileBeforeStrip) or \
494 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
495 shutil.copyfile(GenSecInputFile, FileBeforeStrip)
496 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
497 GenFdsGlobalVariable.GenerateFirmwareImage(
498 StrippedFile,
499 [GenSecInputFile],
500 Strip=True
501 )
502 GenSecInputFile = StrippedFile
503
504 if SectionType == 'TE':
505 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
506 GenFdsGlobalVariable.GenerateFirmwareImage(
507 TeFile,
508 [GenSecInputFile],
509 Type='te'
510 )
511 GenSecInputFile = TeFile
512
513 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
514 OutputFileList.append(OutputFile)
515
516 return OutputFileList
517
518 ## __GenSimpleFileFfs__() method
519 #
520 # Generate FFS
521 #
522 # @param self The object pointer
523 # @param Rule The rule object used to generate section
524 # @param InputFileList The output file list from GenSection
525 # @retval string Generated FFS file name
526 #
527 def __GenSimpleFileFfs__(self, Rule, InputFileList):
528 FfsOutput = self.OutputPath + \
529 os.sep + \
530 self.__ExtendMacro__(Rule.NameGuid) + \
531 '.ffs'
532
533 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
534 InputSection = []
535 SectionAlignments = []
536 for InputFile in InputFileList:
537 InputSection.append(InputFile)
538 SectionAlignments.append(Rule.SectAlignment)
539
540 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
541 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
542 if len(PcdValue) == 0:
543 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
544 % (Rule.NameGuid))
545 if PcdValue.startswith('{'):
546 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
547 RegistryGuidStr = PcdValue
548 if len(RegistryGuidStr) == 0:
549 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
550 % (Rule.NameGuid))
551 self.ModuleGuid = RegistryGuidStr
552
553 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
554 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
555 self.ModuleGuid, Fixed=Rule.Fixed,
556 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
557 SectionAlign=SectionAlignments
558 )
559 return FfsOutput
560
561 ## __GenComplexFileSection__() method
562 #
563 # Generate section by sections in Rule
564 #
565 # @param self The object pointer
566 # @param Rule The rule object used to generate section
567 # @param FvChildAddr Array of the inside FvImage base address
568 # @param FvParentAddr Parent Fv base address
569 # @retval string File name of the generated section file
570 #
571 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
572 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
573 if Rule.KeepReloc != None:
574 self.KeepRelocFromRule = Rule.KeepReloc
575 SectFiles = []
576 SectAlignments = []
577 Index = 1
578 for Sect in Rule.SectionList:
579 SecIndex = '%d' %Index
580 SectList = []
581 #
582 # Convert Fv Section Type for PI1.1 SMM driver.
583 #
584 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:
585 if Sect.SectionType == 'DXE_DEPEX':
586 Sect.SectionType = 'SMM_DEPEX'
587 #
588 # Framework SMM Driver has no SMM_DEPEX section type
589 #
590 if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:
591 if Sect.SectionType == 'SMM_DEPEX':
592 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
593 #
594 # process the inside FvImage from FvSection or GuidSection
595 #
596 if FvChildAddr != []:
597 if isinstance(Sect, FvImageSection):
598 Sect.FvAddr = FvChildAddr.pop(0)
599 elif isinstance(Sect, GuidSection):
600 Sect.FvAddr = FvChildAddr
601 if FvParentAddr != None and isinstance(Sect, GuidSection):
602 Sect.FvParentAddr = FvParentAddr
603
604 if Rule.KeyStringList != []:
605 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
606 else :
607 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
608 for SecName in SectList :
609 SectFiles.append(SecName)
610 SectAlignments.append(Align)
611 Index = Index + 1
612 return SectFiles, SectAlignments
613
614 ## __GenComplexFileFfs__() method
615 #
616 # Generate FFS
617 #
618 # @param self The object pointer
619 # @param Rule The rule object used to generate section
620 # @param InputFileList The output file list from GenSection
621 # @retval string Generated FFS file name
622 #
623 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
624
625 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
626 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
627 if len(PcdValue) == 0:
628 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
629 % (Rule.NameGuid))
630 if PcdValue.startswith('{'):
631 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
632 RegistryGuidStr = PcdValue
633 if len(RegistryGuidStr) == 0:
634 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
635 % (Rule.NameGuid))
636 self.ModuleGuid = RegistryGuidStr
637
638 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
639 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
640 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
641 self.ModuleGuid, Fixed=Rule.Fixed,
642 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
643 SectionAlign=Alignments
644 )
645 return FfsOutput
646
647 ## __GetGenFfsCmdParameter__() method
648 #
649 # Create parameter string for GenFfs
650 #
651 # @param self The object pointer
652 # @param Rule The rule object used to generate section
653 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
654 #
655 def __GetGenFfsCmdParameter__(self, Rule):
656 result = tuple()
657 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
658 if Rule.Fixed != False:
659 result += ('-x',)
660 if Rule.CheckSum != False:
661 result += ('-s',)
662
663 if Rule.Alignment != None and Rule.Alignment != '':
664 result += ('-a', Rule.Alignment)
665
666 return result