Home | History | Annotate | Download | only in GenFds
      1 ## @file

      2 # process GUIDed section generation

      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 Section
     19 import subprocess
     20 from Ffs import Ffs
     21 import Common.LongFilePathOs as os
     22 from GenFdsGlobalVariable import GenFdsGlobalVariable
     23 from CommonDataClass.FdfClass import GuidSectionClassObject
     24 from Common import ToolDefClassObject
     25 import sys
     26 from Common import EdkLogger
     27 from Common.BuildToolError import *
     28 from FvImageSection import FvImageSection
     29 from Common.LongFilePathSupport import OpenLongFilePath as open
     30 from GenFds import FindExtendTool
     31 
     32 ## generate GUIDed section

     33 #

     34 #

     35 class GuidSection(GuidSectionClassObject) :
     36 
     37     ## The constructor

     38     #

     39     #   @param  self        The object pointer

     40     #

     41     def __init__(self):
     42         GuidSectionClassObject.__init__(self)
     43 
     44     ## GenSection() method

     45     #

     46     #   Generate GUIDed section

     47     #

     48     #   @param  self        The object pointer

     49     #   @param  OutputPath  Where to place output file

     50     #   @param  ModuleName  Which module this section belongs to

     51     #   @param  SecNum      Index of section

     52     #   @param  KeyStringList  Filter for inputs of section generation

     53     #   @param  FfsInf      FfsInfStatement object that contains this section data

     54     #   @param  Dict        dictionary contains macro and its value

     55     #   @retval tuple       (Generated file name, section alignment)

     56     #

     57     def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
     58         #

     59         # Generate all section

     60         #

     61         self.KeyStringList = KeyStringList
     62         self.CurrentArchList = GenFdsGlobalVariable.ArchList
     63         if FfsInf != None:
     64             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
     65             self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
     66             self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
     67             self.CurrentArchList = [FfsInf.CurrentArch]
     68 
     69         SectFile = tuple()
     70         SectAlign = []
     71         Index = 0
     72         MaxAlign = None
     73         if self.FvAddr != []:
     74             FvAddrIsSet = True
     75         else:
     76             FvAddrIsSet = False
     77         
     78         if self.ProcessRequired in ("TRUE", "1"):
     79             if self.FvAddr != []:
     80                 #no use FvAddr when the image is processed.

     81                 self.FvAddr = []
     82             if self.FvParentAddr != None:
     83                 #no use Parent Addr when the image is processed.

     84                 self.FvParentAddr = None
     85 
     86         for Sect in self.SectionList:
     87             Index = Index + 1
     88             SecIndex = '%s.%d' % (SecNum, Index)
     89             # set base address for inside FvImage

     90             if isinstance(Sect, FvImageSection):
     91                 if self.FvAddr != []:
     92                     Sect.FvAddr = self.FvAddr.pop(0)
     93                 self.IncludeFvSection = True
     94             elif isinstance(Sect, GuidSection):
     95                 Sect.FvAddr = self.FvAddr
     96                 Sect.FvParentAddr = self.FvParentAddr
     97             ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
     98             if isinstance(Sect, GuidSection):
     99                 if Sect.IncludeFvSection:
    100                     self.IncludeFvSection = Sect.IncludeFvSection
    101 
    102             if align != None:
    103                 if MaxAlign == None:
    104                     MaxAlign = align
    105                 if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
    106                     MaxAlign = align
    107             if ReturnSectList != []:
    108                 if align == None:
    109                     align = "1"
    110                 for file in ReturnSectList:
    111                     SectFile += (file,)
    112                     SectAlign.append(align)
    113 
    114         if MaxAlign != None:
    115             if self.Alignment == None:
    116                 self.Alignment = MaxAlign
    117             else:
    118                 if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
    119                     self.Alignment = MaxAlign
    120 
    121         OutputFile = OutputPath + \
    122                      os.sep + \
    123                      ModuleName + \
    124                      'SEC' + \
    125                      SecNum + \
    126                      Ffs.SectionSuffix['GUIDED']
    127         OutputFile = os.path.normpath(OutputFile)
    128 
    129         ExternalTool = None
    130         ExternalOption = None
    131         if self.NameGuid != None:
    132             ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)
    133 
    134         #

    135         # If not have GUID , call default

    136         # GENCRC32 section

    137         #

    138         if self.NameGuid == None :
    139             GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
    140             GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)
    141             OutputFileList = []
    142             OutputFileList.append(OutputFile)
    143             return OutputFileList, self.Alignment
    144         #or GUID not in External Tool List

    145         elif ExternalTool == None:
    146             EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
    147         else:
    148             DummyFile = OutputFile + ".dummy"
    149             #

    150             # Call GenSection with DUMMY section type.

    151             #

    152             GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign)
    153             #

    154             # Use external tool process the Output

    155             #

    156             TempFile = OutputPath + \
    157                        os.sep + \
    158                        ModuleName + \
    159                        'SEC' + \
    160                        SecNum + \
    161                        '.tmp'
    162             TempFile = os.path.normpath(TempFile)
    163             #

    164             # Remove temp file if its time stamp is older than dummy file

    165             # Just in case the external tool fails at this time but succeeded before

    166             # Error should be reported if the external tool does not generate a new output based on new input

    167             #

    168             if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile):
    169                 os.remove(TempFile)
    170 
    171             FirstCall = False
    172             CmdOption = '-e'
    173             if ExternalOption != None:
    174                 CmdOption = CmdOption + ' ' + ExternalOption
    175             if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
    176                 #FirstCall is only set for the encapsulated flash FV image without process required attribute.

    177                 FirstCall = True
    178             #

    179             # Call external tool

    180             #

    181             ReturnValue = [1]
    182             if FirstCall:
    183                 #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.

    184                 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
    185 
    186             #

    187             # when no call or first call failed, ReturnValue are not 1.

    188             # Call the guided tool with CmdOption

    189             #

    190             if ReturnValue[0] != 0:
    191                 FirstCall = False
    192                 ReturnValue[0] = 0
    193                 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
    194             #

    195             # There is external tool which does not follow standard rule which return nonzero if tool fails

    196             # The output file has to be checked

    197             #

    198             if not os.path.exists(TempFile):
    199                 EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
    200 
    201             FileHandleIn = open(DummyFile, 'rb')
    202             FileHandleIn.seek(0, 2)
    203             InputFileSize = FileHandleIn.tell()
    204 
    205             FileHandleOut = open(TempFile, 'rb')
    206             FileHandleOut.seek(0, 2)
    207             TempFileSize = FileHandleOut.tell()
    208 
    209             Attribute = []
    210             HeaderLength = None
    211             if self.ExtraHeaderSize != -1:
    212                 HeaderLength = str(self.ExtraHeaderSize)
    213 
    214             if self.ProcessRequired == "NONE" and HeaderLength == None:
    215                 if TempFileSize > InputFileSize:
    216                     FileHandleIn.seek(0)
    217                     BufferIn = FileHandleIn.read()
    218                     FileHandleOut.seek(0)
    219                     BufferOut = FileHandleOut.read()
    220                     if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
    221                         HeaderLength = str(TempFileSize - InputFileSize)
    222                 #auto sec guided attribute with process required

    223                 if HeaderLength == None:
    224                     Attribute.append('PROCESSING_REQUIRED')
    225 
    226             FileHandleIn.close()
    227             FileHandleOut.close()
    228 
    229             if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
    230                 # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.

    231                 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
    232 
    233             #

    234             # Call Gensection Add Section Header

    235             #

    236             if self.ProcessRequired in ("TRUE", "1"):
    237                 if 'PROCESSING_REQUIRED' not in Attribute:
    238                     Attribute.append('PROCESSING_REQUIRED')
    239 
    240             if self.AuthStatusValid in ("TRUE", "1"):
    241                 Attribute.append('AUTH_STATUS_VALID')
    242             GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
    243                                                  Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
    244             OutputFileList = []
    245             OutputFileList.append(OutputFile)
    246             if 'PROCESSING_REQUIRED' in Attribute:
    247                 # reset guided section alignment to none for the processed required guided data

    248                 self.Alignment = None
    249                 self.IncludeFvSection = False
    250                 self.ProcessRequired = "TRUE"
    251             return OutputFileList, self.Alignment
    252 
    253 
    254 
    255