git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10680 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			288 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# process GUIDed section generation
 | 
						|
#
 | 
						|
#  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
 | 
						|
#
 | 
						|
#  This program and the accompanying materials
 | 
						|
#  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
#  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
#  http://opensource.org/licenses/bsd-license.php
 | 
						|
#
 | 
						|
#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
#
 | 
						|
 | 
						|
##
 | 
						|
# Import Modules
 | 
						|
#
 | 
						|
import Section
 | 
						|
import subprocess
 | 
						|
from Ffs import Ffs
 | 
						|
import os
 | 
						|
from GenFdsGlobalVariable import GenFdsGlobalVariable
 | 
						|
from CommonDataClass.FdfClass import GuidSectionClassObject
 | 
						|
from Common import ToolDefClassObject
 | 
						|
import sys
 | 
						|
from Common import EdkLogger
 | 
						|
from Common.BuildToolError import *
 | 
						|
from FvImageSection import FvImageSection
 | 
						|
 | 
						|
## generate GUIDed section
 | 
						|
#
 | 
						|
#
 | 
						|
class GuidSection(GuidSectionClassObject) :
 | 
						|
 | 
						|
    ## The constructor
 | 
						|
    #
 | 
						|
    #   @param  self        The object pointer
 | 
						|
    #
 | 
						|
    def __init__(self):
 | 
						|
        GuidSectionClassObject.__init__(self)
 | 
						|
 | 
						|
    ## GenSection() method
 | 
						|
    #
 | 
						|
    #   Generate GUIDed section
 | 
						|
    #
 | 
						|
    #   @param  self        The object pointer
 | 
						|
    #   @param  OutputPath  Where to place output file
 | 
						|
    #   @param  ModuleName  Which module this section belongs to
 | 
						|
    #   @param  SecNum      Index of section
 | 
						|
    #   @param  KeyStringList  Filter for inputs of section generation
 | 
						|
    #   @param  FfsInf      FfsInfStatement object that contains this section data
 | 
						|
    #   @param  Dict        dictionary contains macro and its value
 | 
						|
    #   @retval tuple       (Generated file name, section alignment)
 | 
						|
    #
 | 
						|
    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
 | 
						|
        #
 | 
						|
        # Generate all section
 | 
						|
        #
 | 
						|
        self.KeyStringList = KeyStringList
 | 
						|
        self.CurrentArchList = GenFdsGlobalVariable.ArchList
 | 
						|
        if FfsInf != None:
 | 
						|
            self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
 | 
						|
            self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
 | 
						|
            self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
 | 
						|
            self.CurrentArchList = [FfsInf.CurrentArch]
 | 
						|
 | 
						|
        SectFile  = tuple()
 | 
						|
        SectAlign = []
 | 
						|
        Index = 0
 | 
						|
        MaxAlign = None
 | 
						|
        if self.FvAddr != []:
 | 
						|
            FvAddrIsSet = True
 | 
						|
        else:
 | 
						|
            FvAddrIsSet = False
 | 
						|
        
 | 
						|
        if self.ProcessRequired in ("TRUE", "1"):
 | 
						|
            if self.FvAddr != []:
 | 
						|
                #no use FvAddr when the image is processed.
 | 
						|
                self.FvAddr = []
 | 
						|
            if self.FvParentAddr != None:
 | 
						|
                #no use Parent Addr when the image is processed.
 | 
						|
                self.FvParentAddr = None
 | 
						|
 | 
						|
        for Sect in self.SectionList:
 | 
						|
            Index = Index + 1
 | 
						|
            SecIndex = '%s.%d' %(SecNum,Index)
 | 
						|
            # set base address for inside FvImage
 | 
						|
            if isinstance(Sect, FvImageSection):
 | 
						|
                if self.FvAddr != []:
 | 
						|
                    Sect.FvAddr = self.FvAddr.pop(0)
 | 
						|
                self.IncludeFvSection = True
 | 
						|
            elif isinstance(Sect, GuidSection):
 | 
						|
                Sect.FvAddr = self.FvAddr
 | 
						|
                Sect.FvParentAddr = self.FvParentAddr
 | 
						|
            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList,FfsInf, Dict)
 | 
						|
            if isinstance(Sect, GuidSection):
 | 
						|
                if Sect.IncludeFvSection:
 | 
						|
                    self.IncludeFvSection = Sect.IncludeFvSection
 | 
						|
 | 
						|
            if align != None:
 | 
						|
                if MaxAlign == None:
 | 
						|
                    MaxAlign = align
 | 
						|
                if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
 | 
						|
                    MaxAlign = align
 | 
						|
            if ReturnSectList != []:
 | 
						|
                if align == None:
 | 
						|
                    align = "1"
 | 
						|
                for file in ReturnSectList:
 | 
						|
                    SectFile += (file,)
 | 
						|
                    SectAlign.append(align)
 | 
						|
 | 
						|
        if MaxAlign != None:
 | 
						|
            if self.Alignment == None:
 | 
						|
                self.Alignment = MaxAlign
 | 
						|
            else:
 | 
						|
                if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
 | 
						|
                    self.Alignment = MaxAlign
 | 
						|
 | 
						|
        OutputFile = OutputPath + \
 | 
						|
                     os.sep     + \
 | 
						|
                     ModuleName + \
 | 
						|
                     'SEC'      + \
 | 
						|
                     SecNum     + \
 | 
						|
                     Ffs.SectionSuffix['GUIDED']
 | 
						|
        OutputFile = os.path.normpath(OutputFile)
 | 
						|
 | 
						|
        ExternalTool = None
 | 
						|
        ExternalOption = None
 | 
						|
        if self.NameGuid != None:
 | 
						|
            ExternalTool, ExternalOption = self.__FindExtendTool__()
 | 
						|
 | 
						|
        #
 | 
						|
        # If not have GUID , call default
 | 
						|
        # GENCRC32 section
 | 
						|
        #
 | 
						|
        if self.NameGuid == None :
 | 
						|
            GenFdsGlobalVariable.VerboseLogger( "Use GenSection function Generate CRC32 Section")
 | 
						|
            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)
 | 
						|
            OutputFileList = []
 | 
						|
            OutputFileList.append(OutputFile)
 | 
						|
            return OutputFileList, self.Alignment
 | 
						|
        #or GUID not in External Tool List
 | 
						|
        elif ExternalTool == None:
 | 
						|
            EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
 | 
						|
        else:
 | 
						|
            DummyFile = OutputFile+".dummy"
 | 
						|
            #
 | 
						|
            # Call GenSection with DUMMY section type.
 | 
						|
            #
 | 
						|
            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign)
 | 
						|
            #
 | 
						|
            # Use external tool process the Output
 | 
						|
            #
 | 
						|
            TempFile = OutputPath + \
 | 
						|
                       os.sep     + \
 | 
						|
                       ModuleName + \
 | 
						|
                       'SEC'      + \
 | 
						|
                       SecNum     + \
 | 
						|
                       '.tmp'
 | 
						|
            TempFile = os.path.normpath(TempFile)
 | 
						|
 | 
						|
            FirstCall = False
 | 
						|
            CmdOption = '-e'
 | 
						|
            if ExternalOption != None:
 | 
						|
                CmdOption = CmdOption + ' ' + ExternalOption
 | 
						|
            if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
 | 
						|
                #FirstCall is only set for the encapsulated flash FV image without process required attribute.
 | 
						|
                FirstCall = True
 | 
						|
            #
 | 
						|
            # Call external tool
 | 
						|
            #
 | 
						|
            ReturnValue = [1]
 | 
						|
            if FirstCall:
 | 
						|
                #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
 | 
						|
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
 | 
						|
 | 
						|
            #
 | 
						|
            # when no call or first call failed, ReturnValue are not 1.
 | 
						|
            # Call the guided tool with CmdOption
 | 
						|
            #
 | 
						|
            if ReturnValue[0] != 0:
 | 
						|
                FirstCall = False
 | 
						|
                ReturnValue[0] = 0
 | 
						|
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
 | 
						|
 | 
						|
            FileHandleIn = open(DummyFile,'rb')
 | 
						|
            FileHandleIn.seek(0,2)
 | 
						|
            InputFileSize = FileHandleIn.tell()
 | 
						|
            
 | 
						|
            FileHandleOut = open(TempFile,'rb')
 | 
						|
            FileHandleOut.seek(0,2)
 | 
						|
            TempFileSize = FileHandleOut.tell()
 | 
						|
 | 
						|
            Attribute = []
 | 
						|
            HeaderLength = None
 | 
						|
            if self.ProcessRequired == "NONE":
 | 
						|
                if TempFileSize > InputFileSize and TempFileSize % 4 == 0:
 | 
						|
                    FileHandleIn.seek(0)
 | 
						|
                    BufferIn  = FileHandleIn.read()
 | 
						|
                    FileHandleOut.seek(0)
 | 
						|
                    BufferOut = FileHandleOut.read()
 | 
						|
                    if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
 | 
						|
                        HeaderLength = str(TempFileSize - InputFileSize)
 | 
						|
                #auto sec guided attribute with process required
 | 
						|
                if HeaderLength == None:
 | 
						|
                    Attribute.append('PROCESSING_REQUIRED')
 | 
						|
 | 
						|
            FileHandleIn.close()
 | 
						|
            FileHandleOut.close()
 | 
						|
            
 | 
						|
            if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
 | 
						|
                # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
 | 
						|
                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
 | 
						|
            
 | 
						|
            #
 | 
						|
            # Call Gensection Add Section Header
 | 
						|
            #
 | 
						|
            if self.ProcessRequired in ("TRUE", "1"):
 | 
						|
                if 'PROCESSING_REQUIRED' not in Attribute:
 | 
						|
                    Attribute.append('PROCESSING_REQUIRED')
 | 
						|
                HeaderLength = None
 | 
						|
            if self.AuthStatusValid in ("TRUE", "1"):
 | 
						|
                Attribute.append('AUTH_STATUS_VALID')
 | 
						|
            GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
 | 
						|
                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
 | 
						|
            OutputFileList = []
 | 
						|
            OutputFileList.append(OutputFile)
 | 
						|
            if 'PROCESSING_REQUIRED' in Attribute:
 | 
						|
                # reset guided section alignment to none for the processed required guided data
 | 
						|
                self.Alignment = None
 | 
						|
                self.IncludeFvSection = False
 | 
						|
                self.ProcessRequired = "TRUE"
 | 
						|
            return OutputFileList, self.Alignment
 | 
						|
 | 
						|
    ## __FindExtendTool()
 | 
						|
    #
 | 
						|
    #    Find location of tools to process section data
 | 
						|
    #
 | 
						|
    #   @param  self        The object pointer
 | 
						|
    #
 | 
						|
    def __FindExtendTool__(self):
 | 
						|
        # if user not specify filter, try to deduce it from global data.
 | 
						|
        if self.KeyStringList == None or self.KeyStringList == []:
 | 
						|
            Target = GenFdsGlobalVariable.TargetName
 | 
						|
            ToolChain = GenFdsGlobalVariable.ToolChainTag
 | 
						|
            ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDatabase
 | 
						|
            if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
 | 
						|
                EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
 | 
						|
            self.KeyStringList = [Target+'_'+ToolChain+'_'+self.CurrentArchList[0]]
 | 
						|
            for Arch in self.CurrentArchList:
 | 
						|
                if Target+'_'+ToolChain+'_'+Arch not in self.KeyStringList:
 | 
						|
                    self.KeyStringList.append(Target+'_'+ToolChain+'_'+Arch)
 | 
						|
                    
 | 
						|
        ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDictionary
 | 
						|
        ToolPathTmp = None
 | 
						|
        for ToolDef in ToolDefinition.items():
 | 
						|
            if self.NameGuid == ToolDef[1]:
 | 
						|
                KeyList = ToolDef[0].split('_')
 | 
						|
                Key = KeyList[0] + \
 | 
						|
                      '_'        + \
 | 
						|
                      KeyList[1] + \
 | 
						|
                      '_'        + \
 | 
						|
                      KeyList[2]
 | 
						|
                if Key in self.KeyStringList and KeyList[4] == 'GUID':
 | 
						|
 | 
						|
                    ToolPath = ToolDefinition.get( Key        + \
 | 
						|
                                                   '_'        + \
 | 
						|
                                                   KeyList[3] + \
 | 
						|
                                                   '_'        + \
 | 
						|
                                                   'PATH')
 | 
						|
 | 
						|
                    ToolOption = ToolDefinition.get( Key        + \
 | 
						|
                                                    '_'        + \
 | 
						|
                                                    KeyList[3] + \
 | 
						|
                                                    '_'        + \
 | 
						|
                                                    'FLAGS')
 | 
						|
                    if ToolPathTmp == None:
 | 
						|
                        ToolPathTmp = ToolPath
 | 
						|
                    else:
 | 
						|
                        if ToolPathTmp != ToolPath:
 | 
						|
                            EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))
 | 
						|
                            
 | 
						|
                    
 | 
						|
        return ToolPathTmp, ToolOption
 | 
						|
 | 
						|
 | 
						|
 |