1## @file 2# process FD generation 3# 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7# 8 9## 10# Import Modules 11# 12from __future__ import absolute_import 13from . import Region 14from . import Fv 15import Common.LongFilePathOs as os 16from io import BytesIO 17import sys 18from struct import * 19from .GenFdsGlobalVariable import GenFdsGlobalVariable 20from CommonDataClass.FdfClass import FDClassObject 21from Common import EdkLogger 22from Common.BuildToolError import * 23from Common.Misc import SaveFileOnChange 24from Common.DataType import BINARY_FILE_TYPE_FV 25 26## generate FD 27# 28# 29class FD(FDClassObject): 30 ## The constructor 31 # 32 # @param self The object pointer 33 # 34 def __init__(self): 35 FDClassObject.__init__(self) 36 37 ## GenFd() method 38 # 39 # Generate FD 40 # 41 # @retval string Generated FD file name 42 # 43 def GenFd (self, Flag = False): 44 if self.FdUiName.upper() + 'fd' in GenFdsGlobalVariable.ImageBinDict: 45 return GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] 46 47 # 48 # Print Information 49 # 50 FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd') 51 if not Flag: 52 GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName)) 53 54 Offset = 0x00 55 for item in self.BlockSizeList: 56 Offset = Offset + item[0] * item[1] 57 if Offset != self.Size: 58 EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName) 59 GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!') 60 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict: 61 GenFdsGlobalVariable.VerboseLogger(FvObj) 62 63 HasCapsuleRegion = False 64 for RegionObj in self.RegionList: 65 if RegionObj.RegionType == 'CAPSULE': 66 HasCapsuleRegion = True 67 break 68 if HasCapsuleRegion: 69 TempFdBuffer = BytesIO() 70 PreviousRegionStart = -1 71 PreviousRegionSize = 1 72 73 for RegionObj in self.RegionList : 74 if RegionObj.RegionType == 'CAPSULE': 75 continue 76 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: 77 pass 78 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): 79 pass 80 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: 81 if not Flag: 82 GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) 83 PadRegion = Region.Region() 84 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize 85 PadRegion.Size = RegionObj.Offset - PadRegion.Offset 86 if not Flag: 87 PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) 88 PreviousRegionStart = RegionObj.Offset 89 PreviousRegionSize = RegionObj.Size 90 # 91 # Call each region's AddToBuffer function 92 # 93 if PreviousRegionSize > self.Size: 94 pass 95 GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') 96 RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) 97 98 FdBuffer = BytesIO() 99 PreviousRegionStart = -1 100 PreviousRegionSize = 1 101 for RegionObj in self.RegionList : 102 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: 103 EdkLogger.error("GenFds", GENFDS_ERROR, 104 '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.'\ 105 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) 106 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): 107 EdkLogger.error("GenFds", GENFDS_ERROR, 108 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ 109 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) 110 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: 111 if not Flag: 112 GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) 113 PadRegion = Region.Region() 114 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize 115 PadRegion.Size = RegionObj.Offset - PadRegion.Offset 116 if not Flag: 117 PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) 118 PreviousRegionStart = RegionObj.Offset 119 PreviousRegionSize = RegionObj.Size 120 # 121 # Verify current region fits within allocated FD section Size 122 # 123 if PreviousRegionStart + PreviousRegionSize > self.Size: 124 EdkLogger.error("GenFds", GENFDS_ERROR, 125 'FD %s size too small to fit region with offset 0x%X and size 0x%X' 126 % (self.FdUiName, PreviousRegionStart, PreviousRegionSize)) 127 # 128 # Call each region's AddToBuffer function 129 # 130 GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') 131 RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict, Flag=Flag) 132 # 133 # Write the buffer contents to Fd file 134 # 135 GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') 136 if not Flag: 137 SaveFileOnChange(FdFileName, FdBuffer.getvalue()) 138 FdBuffer.close() 139 GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName 140 return FdFileName 141 142 ## generate flash map file 143 # 144 # @param self The object pointer 145 # 146 def GenFlashMap (self): 147 pass 148 149 150 151 152 153 154 155 156