Home | History | Annotate | Download | only in GenFds
      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 #

     18 import Ffs
     19 import Rule
     20 import Common.LongFilePathOs as os
     21 import StringIO
     22 import subprocess
     23 
     24 from GenFdsGlobalVariable import GenFdsGlobalVariable
     25 from CommonDataClass.FdfClass import FileStatementClassObject
     26 from Common import EdkLogger
     27 from Common.BuildToolError import *
     28 from Common.Misc import GuidStructureByteArrayToGuidString
     29 from GuidSection import GuidSection
     30 from FvImageSection import FvImageSection
     31 from Common.Misc import SaveFileOnChange
     32 from struct import *
     33 
     34 ## generate FFS from FILE

     35 #

     36 #

     37 class 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