1## @file 2# process FFS generation from FILE statement 3# 4# Copyright (c) 2007 - 2016, 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 Ffs 19import Rule 20import Common.LongFilePathOs as os 21import StringIO 22import subprocess 23 24from GenFdsGlobalVariable import GenFdsGlobalVariable 25from CommonDataClass.FdfClass import FileStatementClassObject 26from Common import EdkLogger 27from Common.BuildToolError import * 28from Common.Misc import GuidStructureByteArrayToGuidString 29from GuidSection import GuidSection 30from FvImageSection import FvImageSection 31from Common.Misc import SaveFileOnChange 32from struct import * 33 34## generate FFS from FILE 35# 36# 37class FileStatement (FileStatementClassObject) : 38 ## The constructor 39 # 40 # @param self The object pointer 41 # 42 def __init__(self): 43 FileStatementClassObject.__init__(self) 44 self.CurrentLineNum = None 45 self.CurrentLineContent = None 46 self.FileName = None 47 self.InfFileName = None 48 self.SubAlignment = None 49 50 ## GenFfs() method 51 # 52 # Generate FFS 53 # 54 # @param self The object pointer 55 # @param Dict dictionary contains macro and value pair 56 # @param FvChildAddr Array of the inside FvImage base address 57 # @param FvParentAddr Parent Fv base address 58 # @retval string Generated FFS file name 59 # 60 def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None): 61 62 if self.NameGuid != None and self.NameGuid.startswith('PCD('): 63 PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) 64 if len(PcdValue) == 0: 65 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ 66 % (self.NameGuid)) 67 if PcdValue.startswith('{'): 68 PcdValue = GuidStructureByteArrayToGuidString(PcdValue) 69 RegistryGuidStr = PcdValue 70 if len(RegistryGuidStr) == 0: 71 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ 72 % (self.NameGuid)) 73 self.NameGuid = RegistryGuidStr 74 75 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid) 76 if not os.path.exists(OutputDir): 77 os.makedirs(OutputDir) 78 79 Dict.update(self.DefineVarDict) 80 SectionAlignments = None 81 if self.FvName != None : 82 Buffer = StringIO.StringIO('') 83 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): 84 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName)) 85 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) 86 FileName = Fv.AddToBuffer(Buffer) 87 SectionFiles = [FileName] 88 89 elif self.FdName != None: 90 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): 91 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName)) 92 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper()) 93 FileName = Fd.GenFd() 94 SectionFiles = [FileName] 95 96 elif self.FileName != None: 97 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW': 98 if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment): 99 FileContent = '' 100 MaxAlignIndex = 0 101 MaxAlignValue = 1 102 for Index, File in enumerate(self.FileName): 103 try: 104 f = open(File, 'rb') 105 except: 106 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File)) 107 Content = f.read() 108 f.close() 109 AlignValue = 1 110 if self.SubAlignment[Index] != None: 111 AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index]) 112 if AlignValue > MaxAlignValue: 113 MaxAlignIndex = Index 114 MaxAlignValue = AlignValue 115 FileContent += Content 116 if len(FileContent) % AlignValue != 0: 117 Size = AlignValue - len(FileContent) % AlignValue 118 for i in range(0, Size): 119 FileContent += pack('B', 0xFF) 120 121 if FileContent: 122 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw') 123 SaveFileOnChange(OutputRAWFile, FileContent, True) 124 self.FileName = OutputRAWFile 125 self.SubAlignment = self.SubAlignment[MaxAlignIndex] 126 127 if self.Alignment and self.SubAlignment: 128 if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment): 129 self.Alignment = self.SubAlignment 130 elif self.SubAlignment: 131 self.Alignment = self.SubAlignment 132 133 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) 134 #Replace $(SAPCE) with real space 135 self.FileName = self.FileName.replace('$(SPACE)', ' ') 136 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)] 137 138 else: 139 SectionFiles = [] 140 Index = 0 141 SectionAlignments = [] 142 for section in self.SectionList : 143 Index = Index + 1 144 SecIndex = '%d' %Index 145 # process the inside FvImage from FvSection or GuidSection 146 if FvChildAddr != []: 147 if isinstance(section, FvImageSection): 148 section.FvAddr = FvChildAddr.pop(0) 149 elif isinstance(section, GuidSection): 150 section.FvAddr = FvChildAddr 151 if FvParentAddr != None and isinstance(section, GuidSection): 152 section.FvParentAddr = FvParentAddr 153 154 if self.KeepReloc == False: 155 section.KeepReloc = False 156 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict) 157 if sectList != []: 158 for sect in sectList: 159 SectionFiles.append(sect) 160 SectionAlignments.append(align) 161 162 # 163 # Prepare the parameter 164 # 165 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs') 166 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles, 167 Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType), 168 self.NameGuid, 169 Fixed=self.Fixed, 170 CheckSum=self.CheckSum, 171 Align=self.Alignment, 172 SectionAlign=SectionAlignments 173 ) 174 175 return FfsFileOutput 176 177 178 179