Update Makefile to support FFS file generation with new build option --genfds-multi-thread. Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			209 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # process FD generation
 | |
| #
 | |
| #  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 | |
| #
 | |
| #  This program and the accompanying materials
 | |
| #  are licensed and made available under the terms and conditions of the BSD License
 | |
| #  which accompanies this distribution.  The full text of the license may be found at
 | |
| #  http://opensource.org/licenses/bsd-license.php
 | |
| #
 | |
| #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| #
 | |
| 
 | |
| ##
 | |
| # Import Modules
 | |
| #
 | |
| import Region
 | |
| import Fv
 | |
| import Common.LongFilePathOs as os
 | |
| import StringIO
 | |
| import sys
 | |
| from struct import *
 | |
| from GenFdsGlobalVariable import GenFdsGlobalVariable
 | |
| from CommonDataClass.FdfClass import FDClassObject
 | |
| from Common import EdkLogger
 | |
| from Common.BuildToolError import *
 | |
| from Common.Misc import SaveFileOnChange
 | |
| from GenFds import GenFds
 | |
| 
 | |
| ## generate FD
 | |
| #
 | |
| #
 | |
| class FD(FDClassObject):
 | |
|     ## The constructor
 | |
|     #
 | |
|     #   @param  self        The object pointer
 | |
|     #
 | |
|     def __init__(self):
 | |
|         FDClassObject.__init__(self)
 | |
| 
 | |
|     ## GenFd() method
 | |
|     #
 | |
|     #   Generate FD
 | |
|     #
 | |
|     #   @retval string      Generated FD file name
 | |
|     #
 | |
|     def GenFd (self, Flag = False):
 | |
|         if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys():
 | |
|             return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd']
 | |
| 
 | |
|         #
 | |
|         # Print Information
 | |
|         #
 | |
|         FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd')
 | |
|         if not Flag:
 | |
|             GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName))
 | |
| 
 | |
|         Offset = 0x00
 | |
|         for item in self.BlockSizeList:
 | |
|             Offset = Offset + item[0]  * item[1]
 | |
|         if Offset != self.Size:
 | |
|             EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
 | |
|         GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
 | |
|         for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
 | |
|             GenFdsGlobalVariable.VerboseLogger(FvObj)
 | |
| 
 | |
|         GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################')
 | |
|         self.GenVtfFile()
 | |
| 
 | |
|         HasCapsuleRegion = False
 | |
|         for RegionObj in self.RegionList:
 | |
|             if RegionObj.RegionType == 'CAPSULE':
 | |
|                 HasCapsuleRegion = True
 | |
|                 break
 | |
|         if HasCapsuleRegion:
 | |
|             TempFdBuffer = StringIO.StringIO('')
 | |
|             PreviousRegionStart = -1
 | |
|             PreviousRegionSize = 1
 | |
| 
 | |
|             for RegionObj in self.RegionList :
 | |
|                 if RegionObj.RegionType == 'CAPSULE':
 | |
|                     continue
 | |
|                 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
 | |
|                     pass
 | |
|                 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
 | |
|                     pass
 | |
|                 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
 | |
|                     if not Flag:
 | |
|                         GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
 | |
|                     PadRegion = Region.Region()
 | |
|                     PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
 | |
|                     PadRegion.Size = RegionObj.Offset - PadRegion.Offset
 | |
|                     if not Flag:
 | |
|                         PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
 | |
|                 PreviousRegionStart = RegionObj.Offset
 | |
|                 PreviousRegionSize = RegionObj.Size
 | |
|                 #
 | |
|                 # Call each region's AddToBuffer function
 | |
|                 #
 | |
|                 if PreviousRegionSize > self.Size:
 | |
|                     pass
 | |
|                 GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
 | |
|                 RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
 | |
|         
 | |
|         FdBuffer = StringIO.StringIO('')
 | |
|         PreviousRegionStart = -1
 | |
|         PreviousRegionSize = 1
 | |
|         for RegionObj in self.RegionList :
 | |
|             if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
 | |
|                 EdkLogger.error("GenFds", GENFDS_ERROR,
 | |
|                                 'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\
 | |
|                                 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
 | |
|             elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
 | |
|                 EdkLogger.error("GenFds", GENFDS_ERROR,
 | |
|                                 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
 | |
|                                 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
 | |
|             elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
 | |
|                 if not Flag:
 | |
|                     GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
 | |
|                 PadRegion = Region.Region()
 | |
|                 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
 | |
|                 PadRegion.Size = RegionObj.Offset - PadRegion.Offset
 | |
|                 if not Flag:
 | |
|                     PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
 | |
|             PreviousRegionStart = RegionObj.Offset
 | |
|             PreviousRegionSize = RegionObj.Size
 | |
|             #
 | |
|             # Verify current region fits within allocated FD section Size
 | |
|             #
 | |
|             if PreviousRegionStart + PreviousRegionSize > self.Size:
 | |
|                 EdkLogger.error("GenFds", GENFDS_ERROR,
 | |
|                                 'FD %s size too small to fit region with offset 0x%X and size 0x%X'
 | |
|                                 % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
 | |
|             #
 | |
|             # Call each region's AddToBuffer function
 | |
|             #
 | |
|             GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
 | |
|             RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict,Flag=Flag)
 | |
|         #
 | |
|         # Write the buffer contents to Fd file
 | |
|         #
 | |
|         GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
 | |
|         if not Flag:
 | |
|             SaveFileOnChange(FdFileName, FdBuffer.getvalue())
 | |
|         FdBuffer.close()
 | |
|         GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
 | |
|         return FdFileName
 | |
| 
 | |
|     ## generate VTF
 | |
|     #
 | |
|     #   @param  self        The object pointer
 | |
|     #
 | |
|     def GenVtfFile (self) :
 | |
|         #
 | |
|         # Get this Fd's all Fv name
 | |
|         #
 | |
|         FvAddDict ={}
 | |
|         FvList = []
 | |
|         for RegionObj in self.RegionList:
 | |
|             if RegionObj.RegionType == 'FV':
 | |
|                 if len(RegionObj.RegionDataList) == 1:
 | |
|                     RegionData = RegionObj.RegionDataList[0]
 | |
|                     FvList.append(RegionData.upper())
 | |
|                     FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
 | |
|                                                 RegionObj.Offset, RegionObj.Size)
 | |
|                 else:
 | |
|                     Offset = RegionObj.Offset
 | |
|                     for RegionData in RegionObj.RegionDataList:
 | |
|                         FvList.append(RegionData.upper())
 | |
|                         FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
 | |
|                         if len(FvObj.BlockSizeList) < 1:
 | |
|                             EdkLogger.error("GenFds", GENFDS_ERROR,
 | |
|                                             'FV.%s must point out FVs blocksize and Fv BlockNum' \
 | |
|                                             % FvObj.UiFvName)
 | |
|                         else:
 | |
|                             Size = 0
 | |
|                             for blockStatement in FvObj.BlockSizeList:
 | |
|                                 Size = Size + blockStatement[0] * blockStatement[1]
 | |
|                             FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
 | |
|                                                              Offset, Size)
 | |
|                             Offset = Offset + Size
 | |
|         #
 | |
|         # Check whether this Fd need VTF
 | |
|         #
 | |
|         Flag = False
 | |
|         for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList:
 | |
|             compLocList = VtfObj.GetFvList()
 | |
|             if set(compLocList).issubset(FvList):
 | |
|                 Flag = True
 | |
|                 break
 | |
|         if Flag == True:
 | |
|             self.vtfRawDict = VtfObj.GenVtf(FvAddDict)
 | |
| 
 | |
|     ## generate flash map file
 | |
|     #
 | |
|     #   @param  self        The object pointer
 | |
|     #
 | |
|     def GenFlashMap (self):
 | |
|         pass
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |