1## @file 2# process FD generation 3# 4# Copyright (c) 2007 - 2014, 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# 18import Region 19import Fv 20import Common.LongFilePathOs as os 21import StringIO 22import sys 23from struct import * 24from GenFdsGlobalVariable import GenFdsGlobalVariable 25from CommonDataClass.FdfClass import FDClassObject 26from Common import EdkLogger 27from Common.BuildToolError import * 28from Common.Misc import SaveFileOnChange 29from GenFds import GenFds 30 31## generate FD 32# 33# 34class FD(FDClassObject): 35 ## The constructor 36 # 37 # @param self The object pointer 38 # 39 def __init__(self): 40 FDClassObject.__init__(self) 41 42 ## GenFd() method 43 # 44 # Generate FD 45 # 46 # @retval string Generated FD file name 47 # 48 def GenFd (self): 49 if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys(): 50 return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] 51 52 # 53 # Print Information 54 # 55 GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName) 56 Offset = 0x00 57 for item in self.BlockSizeList: 58 Offset = Offset + item[0] * item[1] 59 if Offset != self.Size: 60 EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName) 61 GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!') 62 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict: 63 GenFdsGlobalVariable.VerboseLogger(FvObj) 64 65 GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################') 66 self.GenVtfFile() 67 68 TempFdBuffer = StringIO.StringIO('') 69 PreviousRegionStart = -1 70 PreviousRegionSize = 1 71 72 for RegionObj in self.RegionList : 73 if RegionObj.RegionType == 'CAPSULE': 74 continue 75 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: 76 pass 77 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): 78 pass 79 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: 80 GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) 81 PadRegion = Region.Region() 82 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize 83 PadRegion.Size = RegionObj.Offset - PadRegion.Offset 84 PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) 85 PreviousRegionStart = RegionObj.Offset 86 PreviousRegionSize = RegionObj.Size 87 # 88 # Call each region's AddToBuffer function 89 # 90 if PreviousRegionSize > self.Size: 91 pass 92 GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') 93 RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) 94 95 FdBuffer = StringIO.StringIO('') 96 PreviousRegionStart = -1 97 PreviousRegionSize = 1 98 for RegionObj in self.RegionList : 99 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: 100 EdkLogger.error("GenFds", GENFDS_ERROR, 101 '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.'\ 102 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) 103 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): 104 EdkLogger.error("GenFds", GENFDS_ERROR, 105 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ 106 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) 107 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: 108 GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) 109 PadRegion = Region.Region() 110 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize 111 PadRegion.Size = RegionObj.Offset - PadRegion.Offset 112 PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) 113 PreviousRegionStart = RegionObj.Offset 114 PreviousRegionSize = RegionObj.Size 115 # 116 # Verify current region fits within allocated FD section Size 117 # 118 if PreviousRegionStart + PreviousRegionSize > self.Size: 119 EdkLogger.error("GenFds", GENFDS_ERROR, 120 'FD %s size too small to fit region with offset 0x%X and size 0x%X' 121 % (self.FdUiName, PreviousRegionStart, PreviousRegionSize)) 122 # 123 # Call each region's AddToBuffer function 124 # 125 GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') 126 RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) 127 # 128 # Create a empty Fd file 129 # 130 GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file') 131 FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,self.FdUiName + '.fd') 132 # 133 # Write the buffer contents to Fd file 134 # 135 GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') 136 SaveFileOnChange(FdFileName, FdBuffer.getvalue()) 137 FdBuffer.close(); 138 GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName 139 return FdFileName 140 141 ## generate VTF 142 # 143 # @param self The object pointer 144 # 145 def GenVtfFile (self) : 146 # 147 # Get this Fd's all Fv name 148 # 149 FvAddDict ={} 150 FvList = [] 151 for RegionObj in self.RegionList: 152 if RegionObj.RegionType == 'FV': 153 if len(RegionObj.RegionDataList) == 1: 154 RegionData = RegionObj.RegionDataList[0] 155 FvList.append(RegionData.upper()) 156 FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ 157 RegionObj.Offset, RegionObj.Size) 158 else: 159 Offset = RegionObj.Offset 160 for RegionData in RegionObj.RegionDataList: 161 FvList.append(RegionData.upper()) 162 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) 163 if len(FvObj.BlockSizeList) < 1: 164 EdkLogger.error("GenFds", GENFDS_ERROR, 165 'FV.%s must point out FVs blocksize and Fv BlockNum' \ 166 % FvObj.UiFvName) 167 else: 168 Size = 0 169 for blockStatement in FvObj.BlockSizeList: 170 Size = Size + blockStatement[0] * blockStatement[1] 171 FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ 172 Offset, Size) 173 Offset = Offset + Size 174 # 175 # Check whether this Fd need VTF 176 # 177 Flag = False 178 for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList: 179 compLocList = VtfObj.GetFvList() 180 if set(compLocList).issubset(FvList): 181 Flag = True 182 break 183 if Flag == True: 184 self.vtfRawDict = VtfObj.GenVtf(FvAddDict) 185 186 ## generate flash map file 187 # 188 # @param self The object pointer 189 # 190 def GenFlashMap (self): 191 pass 192 193 194 195 196 197 198 199 200