From 30fdf1140b8d1ce93f3821d986fa165552023440 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 17 Jul 2009 09:10:31 +0000 Subject: Check In tool source code based on Build tool project revision r1655. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524 --- BaseTools/Source/Python/GenFds/AprioriSection.py | 118 + BaseTools/Source/Python/GenFds/Attribute.py | 28 + BaseTools/Source/Python/GenFds/Capsule.py | 89 + BaseTools/Source/Python/GenFds/CapsuleData.py | 84 + .../Source/Python/GenFds/ComponentStatement.py | 29 + BaseTools/Source/Python/GenFds/CompressSection.py | 87 + BaseTools/Source/Python/GenFds/DataSection.py | 109 + BaseTools/Source/Python/GenFds/DepexSection.py | 102 + BaseTools/Source/Python/GenFds/EfiSection.py | 262 ++ BaseTools/Source/Python/GenFds/Fd.py | 169 + BaseTools/Source/Python/GenFds/FdfParser.py | 3778 ++++++++++++++++++++ BaseTools/Source/Python/GenFds/Ffs.py | 81 + BaseTools/Source/Python/GenFds/FfsFileStatement.py | 118 + BaseTools/Source/Python/GenFds/FfsInfStatement.py | 582 +++ BaseTools/Source/Python/GenFds/Fv.py | 215 ++ BaseTools/Source/Python/GenFds/FvImageSection.py | 90 + BaseTools/Source/Python/GenFds/GenFds.py | 486 +++ .../Source/Python/GenFds/GenFdsGlobalVariable.py | 472 +++ BaseTools/Source/Python/GenFds/GuidSection.py | 190 + .../Source/Python/GenFds/OptRomFileStatement.py | 50 + .../Source/Python/GenFds/OptRomInfStatement.py | 147 + BaseTools/Source/Python/GenFds/OptionRom.py | 140 + BaseTools/Source/Python/GenFds/Region.py | 240 ++ BaseTools/Source/Python/GenFds/Rule.py | 29 + BaseTools/Source/Python/GenFds/RuleComplexFile.py | 30 + BaseTools/Source/Python/GenFds/RuleSimpleFile.py | 30 + BaseTools/Source/Python/GenFds/Section.py | 153 + BaseTools/Source/Python/GenFds/UiSection.py | 77 + BaseTools/Source/Python/GenFds/VerSection.py | 82 + BaseTools/Source/Python/GenFds/Vtf.py | 188 + BaseTools/Source/Python/GenFds/__init__.py | 0 31 files changed, 8255 insertions(+) create mode 100644 BaseTools/Source/Python/GenFds/AprioriSection.py create mode 100644 BaseTools/Source/Python/GenFds/Attribute.py create mode 100644 BaseTools/Source/Python/GenFds/Capsule.py create mode 100644 BaseTools/Source/Python/GenFds/CapsuleData.py create mode 100644 BaseTools/Source/Python/GenFds/ComponentStatement.py create mode 100644 BaseTools/Source/Python/GenFds/CompressSection.py create mode 100644 BaseTools/Source/Python/GenFds/DataSection.py create mode 100644 BaseTools/Source/Python/GenFds/DepexSection.py create mode 100644 BaseTools/Source/Python/GenFds/EfiSection.py create mode 100644 BaseTools/Source/Python/GenFds/Fd.py create mode 100644 BaseTools/Source/Python/GenFds/FdfParser.py create mode 100644 BaseTools/Source/Python/GenFds/Ffs.py create mode 100644 BaseTools/Source/Python/GenFds/FfsFileStatement.py create mode 100644 BaseTools/Source/Python/GenFds/FfsInfStatement.py create mode 100644 BaseTools/Source/Python/GenFds/Fv.py create mode 100644 BaseTools/Source/Python/GenFds/FvImageSection.py create mode 100644 BaseTools/Source/Python/GenFds/GenFds.py create mode 100644 BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py create mode 100644 BaseTools/Source/Python/GenFds/GuidSection.py create mode 100644 BaseTools/Source/Python/GenFds/OptRomFileStatement.py create mode 100644 BaseTools/Source/Python/GenFds/OptRomInfStatement.py create mode 100644 BaseTools/Source/Python/GenFds/OptionRom.py create mode 100644 BaseTools/Source/Python/GenFds/Region.py create mode 100644 BaseTools/Source/Python/GenFds/Rule.py create mode 100644 BaseTools/Source/Python/GenFds/RuleComplexFile.py create mode 100644 BaseTools/Source/Python/GenFds/RuleSimpleFile.py create mode 100644 BaseTools/Source/Python/GenFds/Section.py create mode 100644 BaseTools/Source/Python/GenFds/UiSection.py create mode 100644 BaseTools/Source/Python/GenFds/VerSection.py create mode 100644 BaseTools/Source/Python/GenFds/Vtf.py create mode 100644 BaseTools/Source/Python/GenFds/__init__.py (limited to 'BaseTools/Source/Python/GenFds') diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py new file mode 100644 index 0000000000..92a9794f51 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/AprioriSection.py @@ -0,0 +1,118 @@ +## @file +# process APRIORI file data and generate PEI/DXE APRIORI file +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from struct import * +import os +import StringIO +import FfsFileStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import AprioriSectionClassObject +from Common.String import * +from Common.Misc import SaveFileOnChange,PathClass +from Common import EdkLogger +from Common.BuildToolError import * + +## process APRIORI file data and generate PEI/DXE APRIORI file +# +# +class AprioriSection (AprioriSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + AprioriSectionClassObject.__init__(self) + self.AprioriType = "" + + ## GenFfs() method + # + # Generate FFS for APRIORI file + # + # @param self The object pointer + # @param FvName for whom apriori file generated + # @param Dict dictionary contains macro and its value + # @retval string Generated file name + # + def GenFfs (self, FvName, Dict = {}): + DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881" + PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6" + Buffer = StringIO.StringIO('') + AprioriFileGuid = DXE_GUID + if self.AprioriType == "PEI": + AprioriFileGuid = PEI_GUID + OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \ + GenFdsGlobalVariable.FfsDir,\ + AprioriFileGuid + FvName) + if not os.path.exists(OutputAprFilePath) : + os.makedirs(OutputAprFilePath) + + OutputAprFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.Apri' ) + AprFfsFileName = os.path.join (OutputAprFilePath,\ + AprioriFileGuid + FvName + '.Ffs') + + Dict.update(self.DefineVarDict) + for FfsObj in self.FfsList : + Guid = "" + if isinstance(FfsObj, FfsFileStatement.FileStatement): + Guid = FfsObj.NameGuid + else: + InfFileName = NormPath(FfsObj.InfFileName) + Arch = FfsObj.GetCurrentArch() + + if Arch != None: + Dict['$(ARCH)'] = Arch + InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch) + + if Arch != None: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch] + Guid = Inf.Guid + + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON'] + Guid = Inf.Guid + + self.BinFileList = Inf.Module.Binaries + if self.BinFileList == []: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, + "INF %s not found in build ARCH %s!" \ + % (InfFileName, GenFdsGlobalVariable.ArchList)) + + + GuidPart = Guid.split('-') + Buffer.write(pack('I', long(GuidPart[0], 16))) + Buffer.write(pack('H', int(GuidPart[1], 16))) + Buffer.write(pack('H', int(GuidPart[2], 16))) + + for Num in range(2): + Char = GuidPart[3][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + for Num in range(6): + Char = GuidPart[4][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + SaveFileOnChange(OutputAprFileName, Buffer.getvalue()) + + RawSectionFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.raw' ) + GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW') + GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName], + 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid) + + return AprFfsFileName + diff --git a/BaseTools/Source/Python/GenFds/Attribute.py b/BaseTools/Source/Python/GenFds/Attribute.py new file mode 100644 index 0000000000..67f9956e1d --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Attribute.py @@ -0,0 +1,28 @@ +## @file +# name value pair +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# + +## name value pair +# +# +class Attribute: + ## The constructor + # + # @param self The object pointer + def __init__(self): + self.Name = None + self.Value = None \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/Capsule.py b/BaseTools/Source/Python/GenFds/Capsule.py new file mode 100644 index 0000000000..7f17fcda68 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Capsule.py @@ -0,0 +1,89 @@ +## @file +# generate capsule +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import CapsuleClassObject +import os +import subprocess +import StringIO +from Common.Misc import SaveFileOnChange + + +T_CHAR_LF = '\n' + +## create inf file describes what goes into capsule and call GenFv to generate capsule +# +# +class Capsule (CapsuleClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CapsuleClassObject.__init__(self) + # For GenFv + self.BlockSize = None + # For GenFv + self.BlockNum = None + + ## Generate capsule + # + # @param self The object pointer + # + def GenCapsule(self): + CapInfFile = self.GenCapInf() + CapInfFile.writelines("[files]" + T_CHAR_LF) + + for CapsuleDataObj in self.CapsuleDataList : + FileName = CapsuleDataObj.GenCapsuleSubItem() + CapInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + SaveFileOnChange(self.CapInfFileName, CapInfFile.getvalue(), False) + CapInfFile.close() + # + # Call GenFv tool to generate capsule + # + CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + CapOutputFile = CapOutputFile + '.Cap' + GenFdsGlobalVariable.GenerateFirmwareVolume( + CapOutputFile, + [self.CapInfFileName], + Capsule=True + ) + GenFdsGlobalVariable.SharpCounter = 0 + + ## Generate inf file for capsule + # + # @param self The object pointer + # @retval file inf file object + # + def GenCapInf(self): + self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiCapsuleName + "_Cap" + '.inf') + CapInfFile = StringIO.StringIO() #open (self.CapInfFileName , 'w+') + + CapInfFile.writelines("[options]" + T_CHAR_LF) + + for Item in self.TokensDict.keys(): + CapInfFile.writelines("EFI_" + \ + Item + \ + ' = ' + \ + self.TokensDict.get(Item) + \ + T_CHAR_LF) + + return CapInfFile diff --git a/BaseTools/Source/Python/GenFds/CapsuleData.py b/BaseTools/Source/Python/GenFds/CapsuleData.py new file mode 100644 index 0000000000..db29737963 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/CapsuleData.py @@ -0,0 +1,84 @@ +## @file +# generate capsule +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Ffs +from GenFdsGlobalVariable import GenFdsGlobalVariable +import StringIO + +## base class for capsule data +# +# +class CapsuleData: + ## The constructor + # + # @param self The object pointer + def __init__(self): + pass + + ## generate capsule data + # + # @param self The object pointer + def GenCapsuleSubItem(self): + pass + +## FFS class for capsule data +# +# +class CapsuleFfs (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init_(self) : + self.Ffs = None + + ## generate FFS capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + FfsFile = self.Ffs.GenFfs() + return FfsFile + +## FV class for capsule data +# +# +class CapsuleFv (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.FvName = None + + ## generate FV capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + if self.FvName.find('.fv') == -1: + if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) + FdBuffer = StringIO.StringIO('') + FvFile = FvObj.AddToBuffer(FdBuffer) + return FvFile + + else: + FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName) + return FvFile diff --git a/BaseTools/Source/Python/GenFds/ComponentStatement.py b/BaseTools/Source/Python/GenFds/ComponentStatement.py new file mode 100644 index 0000000000..8a7540fe25 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/ComponentStatement.py @@ -0,0 +1,29 @@ +## @file +# VTF components +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from CommonDataClass.FdfClass import ComponentStatementClassObject + +## VTF components +# +# +class ComponentStatement (ComponentStatementClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + ComponentStatementClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py new file mode 100644 index 0000000000..4a32ea4458 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/CompressSection.py @@ -0,0 +1,87 @@ +## @file +# process compress section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from Ffs import Ffs +import Section +import subprocess +import os +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import CompressSectionClassObject + +## generate compress section +# +# +class CompressSection (CompressSectionClassObject) : + + ## compress types: PI standard and non PI standard + CompTypeDict = { + 'PI_STD' : 'PI_STD', + 'NON_PI_STD' : 'NON_PI_STD' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CompressSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed 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 = {}): + + if FfsInf != None: + self.CompType = FfsInf.__ExtendMacro__(self.CompType) + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + + SectFiles = tuple() + Index = 0 + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' %(SecNum, Index) + ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict) + if ReturnSectList != []: + for FileData in ReturnSectList: + SectFiles += (FileData,) + + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + Ffs.SectionSuffix['COMPRESS'] + OutputFile = os.path.normpath(OutputFile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'], + CompressionType=self.CompTypeDict[self.CompType]) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + + diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py new file mode 100644 index 0000000000..7f24b51fc3 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -0,0 +1,109 @@ +## @file +# process data section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import DataSectionClassObject +import shutil + +## generate data section +# +# +class DataSection (DataSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DataSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed 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 list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + # + # Prepare the parameter of GenSection + # + if FfsFile != None: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict, FfsFile.CurrentArch) + else: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict) + + """Check Section file exist or not !""" + + if not os.path.exists(self.SectFileName): + self.SectFileName = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, + self.SectFileName) + + """Copy Map file to Ffs output""" + Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName) + if Filename[(len(Filename)-4):] == '.efi': + MapFile = Filename.replace('.efi', '.map') + if os.path.exists(MapFile): + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + shutil.copyfile(MapFile, CopyMapFile) + + NoStrip = True + if self.SecType in ('TE', 'PE32'): + if self.KeepReloc != None: + NoStrip = self.KeepReloc + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(self.SectFileName, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Strip=True + ) + self.SectFileName = StrippedFile + + if self.SecType == 'TE': + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Type='te' + ) + self.SectFileName = TeFile + + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType)) + OutputFile = os.path.normpath(OutputFile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType)) + FileList = [OutputFile] + return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py new file mode 100644 index 0000000000..1c8c82a72e --- /dev/null +++ b/BaseTools/Source/Python/GenFds/DepexSection.py @@ -0,0 +1,102 @@ +## @file +# process depex section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import DepexSectionClassObject +from AutoGen.GenDepex import DependencyExpression +import shutil +from Common import EdkLogger +from Common.BuildToolError import * + +## generate data section +# +# +class DepexSection (DepexSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DepexSectionClassObject.__init__(self) + + def __FindGuidValue(self, CName): + for Arch in GenFdsGlobalVariable.ArchList: + for PkgDb in GenFdsGlobalVariable.WorkSpace.PackageList: + if CName in PkgDb.Ppis: + return PkgDb.Ppis[CName] + if CName in PkgDb.Protocols: + return PkgDb.Protocols[CName] + if CName in PkgDb.Guids: + return PkgDb.Guids[CName] + return None + + ## GenSection() method + # + # Generate compressed 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 list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + + self.Expression = self.Expression.replace("\n", " ").replace("\r", " ") + ExpList = self.Expression.split() + ExpGuidDict = {} + + for Exp in ExpList: + if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'): + GuidStr = self.__FindGuidValue(Exp) + if GuidStr == None: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, + "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName)) + + ExpGuidDict[Exp] = GuidStr + + for Item in ExpGuidDict: + self.Expression = self.Expression.replace(Item, ExpGuidDict[Item]) + + self.Expression = self.Expression.strip() + ModuleType = (self.DepexType.startswith('PEI') and ['PEIM'] or ['DXE_DRIVER'])[0] + if self.DepexType.startswith('SMM'): + ModuleType = 'SMM_DRIVER' + InputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx') + InputFile = os.path.normpath(InputFile) + + Dpx = DependencyExpression(self.Expression, ModuleType) + Dpx.Generate(InputFile) + + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.depex') + if self.DepexType.startswith('SMM'): + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.smm') + OutputFile = os.path.normpath(OutputFile) + SecType = (self.DepexType.startswith('PEI') and ['PEI_DEPEX'] or ['DXE_DEPEX'])[0] + if self.DepexType.startswith('SMM'): + SecType = 'SMM_DEPEX' + + GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType)) + FileList = [OutputFile] + return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py new file mode 100644 index 0000000000..2c112ed5cb --- /dev/null +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -0,0 +1,262 @@ +## @file +# process rule section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import EfiSectionClassObject +import shutil +from Common import EdkLogger +from Common.BuildToolError import * + +## generate rule section +# +# +class EfiSection (EfiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + EfiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate rule 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 list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) : + + if self.FileName != None and self.FileName.startswith('PCD('): + self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) + """Prepare the parameter of GenSection""" + if FfsInf != None : + InfFileName = FfsInf.InfFileName + SectionType = FfsInf.__ExtendMacro__(self.SectionType) + Filename = FfsInf.__ExtendMacro__(self.FileName) + BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + StringData = FfsInf.__ExtendMacro__(self.StringData) + NoStrip = True + if FfsInf.ModuleType in ('SEC', 'PEI_CORE', 'PEIM') and SectionType in ('TE', 'PE32'): + if FfsInf.KeepReloc != None: + NoStrip = FfsInf.KeepReloc + elif FfsInf.KeepRelocFromRule != None: + NoStrip = FfsInf.KeepRelocFromRule + elif self.KeepReloc != None: + NoStrip = self.KeepReloc + elif FfsInf.ShadowFromInfFile != None: + NoStrip = FfsInf.ShadowFromInfFile + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName) + + """If the file name was pointed out, add it in FileList""" + FileList = [] + if Filename != None: + Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict) + if not self.Optional: + FileList.append(Filename) + elif os.path.exists(Filename): + FileList.append(Filename) + else: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict) + if IsSect : + return FileList, self.Alignment + + Index = 0 + + """ If Section type is 'VERSION'""" + OutputFileList = [] + if SectionType == 'VERSION': + + InfOverrideVerString = False + if FfsInf.Version != None: + #StringData = FfsInf.Version + BuildNum = FfsInf.Version + InfOverrideVerString = True + + if InfOverrideVerString: + #VerTuple = ('-n', '"' + StringData + '"') + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=StringData, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + f = open(File, 'r') + VerString = f.read() + f.close() +# VerTuple = ('-n', '"' + VerString + '"') + BuildNum = VerString + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + else: +# if StringData != None and len(StringData) > 0: +# VerTuple = ('-n', '"' + StringData + '"') +# else: +# VerTuple = tuple() +# VerString = ' ' + ' '.join(VerTuple) + BuildNum = StringData + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + BuildNumString = ' ' + ' '.join(BuildNumTuple) + + #if VerString == '' and + if BuildNumString == '': + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName) + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + # + # If Section Type is 'UI' + # + elif SectionType == 'UI': + + InfOverrideUiString = False + if FfsInf.Ui != None: + StringData = FfsInf.Ui + InfOverrideUiString = True + + if InfOverrideUiString: + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + f = open(File, 'r') + UiString = f.read() + f.close() + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=UiString) + OutputFileList.append(OutputFile) + else: + if StringData != None and len(StringData) > 0: + UiTuple = ('-n', '"' + StringData + '"') + else: + UiTuple = tuple() + + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return '', None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName) + + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData) + OutputFileList.append(OutputFile) + + + else: + """If File List is empty""" + if FileList == [] : + if self.Optional == True: + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) + + else: + """Convert the File to Section file one by one """ + for File in FileList: + """ Copy Map file to FFS output path """ + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + File = GenFdsGlobalVariable.MacroExtend(File, Dict) + if File[(len(File)-4):] == '.efi': + MapFile = File.replace('.efi', '.map') + if os.path.exists(MapFile): + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + shutil.copyfile(MapFile, CopyMapFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(File, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict)], + Strip=True + ) + File = StrippedFile + """For TE Section call GenFw to generate TE image""" + + if SectionType == 'TE': + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict)], + Type='te' + ) + File = TeFile + + """Call GenSection""" + GenFdsGlobalVariable.GenerateSection(OutputFile, + [GenFdsGlobalVariable.MacroExtend(File)], + Section.Section.SectionType.get (SectionType) + ) + OutputFileList.append(OutputFile) + + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py new file mode 100644 index 0000000000..99baa6abe5 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Fd.py @@ -0,0 +1,169 @@ +## @file +# process FD generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Region +import Fv +import os +import StringIO +import sys +from struct import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import FDClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import SaveFileOnChange + +## generate FD +# +# +class FD(FDClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FDClassObject.__init__(self) + + ## GenFd() method + # + # Generate FD + # + # @param self The object pointer + # @param FvBinDict dictionary contains generated FV name and its file name + # @retval string Generated FD file name + # + def GenFd (self, FvBinDict): + # + # Print Information + # + GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName) + Offset = 0x00 + for item in self.BlockSizeList: + Offset = Offset + item[0] * item[1] + if Offset != self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName) + GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!') + for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + GenFdsGlobalVariable.VerboseLogger(FvObj) + + GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################') + self.GenVtfFile() + + FdBuffer = StringIO.StringIO('') + PreviousRegionStart = -1 + PreviousRegionSize = 1 + for RegionObj in self.RegionList : + if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: + EdkLogger.error("GenFds", GENFDS_ERROR, + '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.'\ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + PadRegion = Region.Region() + PadRegion.Offset = PreviousRegionStart + PreviousRegionSize + PadRegion.Size = RegionObj.Offset - PadRegion.Offset + PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict) + PreviousRegionStart = RegionObj.Offset + PreviousRegionSize = RegionObj.Size + # + # Call each region's AddToBuffer function + # + if PreviousRegionSize > self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s size too small' % self.FdUiName) + GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') + RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict) + # + # Create a empty Fd file + # + GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file') + FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.FdUiName + '.fd') + #FdFile = open(FdFileName, 'wb') + + # + # Write the buffer contents to Fd file + # + GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') + SaveFileOnChange(FdFileName, FdBuffer.getvalue()) + #FdFile.write(FdBuffer.getvalue()); + #FdFile.close(); + FdBuffer.close(); + return FdFileName + + ## generate VTF + # + # @param self The object pointer + # + def GenVtfFile (self) : + # + # Get this Fd's all Fv name + # + FvAddDict ={} + FvList = [] + for RegionObj in self.RegionList: + if RegionObj.RegionType == 'FV': + if len(RegionObj.RegionDataList) == 1: + RegionData = RegionObj.RegionDataList[0] + FvList.append(RegionData.upper()) + FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ + RegionObj.Offset, RegionObj.Size) + else: + Offset = RegionObj.Offset + for RegionData in RegionObj.RegionDataList: + FvList.append(RegionData.upper()) + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) + if len(FvObj.BlockSizeList) < 1: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'FV.%s must point out FVs blocksize and Fv BlockNum' \ + % FvObj.UiFvName) + else: + Size = 0 + for blockStatement in FvObj.BlockSizeList: + Size = Size + blockStatement[0] * blockStatement[1] + FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ + Offset, Size) + Offset = Offset + Size + # + # Check whether this Fd need VTF + # + Flag = False + for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList: + compLocList = VtfObj.GetFvList() + if set(compLocList).issubset(FvList): + Flag = True + break + if Flag == True: + self.vtfRawDict = VtfObj.GenVtf(FvAddDict) + + ## generate flash map file + # + # @param self The object pointer + # + def GenFlashMap (self): + pass + + + + + + + + diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py new file mode 100644 index 0000000000..0bf8f5514b --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -0,0 +1,3778 @@ +## @file +# parse FDF file +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Fd +import Region +import Fv +import AprioriSection +import FfsInfStatement +import FfsFileStatement +import VerSection +import UiSection +import FvImageSection +import DataSection +import DepexSection +import CompressSection +import GuidSection +import Capsule +import CapsuleData +import Rule +import RuleComplexFile +import RuleSimpleFile +import EfiSection +import Vtf +import ComponentStatement +import OptionRom +import OptRomInfStatement +import OptRomFileStatement + +from Common.BuildToolError import * +from Common import EdkLogger + +import re +import os + +##define T_CHAR_SPACE ' ' +##define T_CHAR_NULL '\0' +##define T_CHAR_CR '\r' +##define T_CHAR_TAB '\t' +##define T_CHAR_LF '\n' +##define T_CHAR_SLASH '/' +##define T_CHAR_BACKSLASH '\\' +##define T_CHAR_DOUBLE_QUOTE '\"' +##define T_CHAR_SINGLE_QUOTE '\'' +##define T_CHAR_STAR '*' +##define T_CHAR_HASH '#' + +(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \ +T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \ +(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#') + +SEPERATOR_TUPLE = ('=', '|', ',', '{', '}') + +IncludeFileList = [] +# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF +InputMacroDict = {} +# All Macro values when parsing file, not replace existing Macro +AllMacroList = [] + +def GetRealFileLine (File, Line): + + InsertedLines = 0 + for Profile in IncludeFileList: + if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1) + if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList) + + return (File, Line - InsertedLines) + +## The exception class that used to report error messages when parsing FDF +# +# Currently the "ToolName" is set to be "FDF Parser". +# +class Warning (Exception): + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param File The FDF name + # @param Line The Line number that error occurs + # + def __init__(self, Str, File = None, Line = None): + + FileLineTuple = GetRealFileLine(File, Line) + self.FileName = FileLineTuple[0] + self.LineNumber = FileLineTuple[1] + self.Message = Str + self.ToolName = 'FdfParser' + + def __str__(self): + return self.Message + +## The MACRO class that used to record macro value data when parsing include file +# +# +class MacroProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName, Line): + self.FileName = FileName + self.DefinedAtLine = Line + self.MacroName = None + self.MacroValue = None + +## The Include file content class that used to record file data when parsing include file +# +# May raise Exception when opening file. +# +class IncludeFileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileName = FileName + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + self.InsertStartLineNumber = None + self.InsertAdjust = 0 + +## The FDF content class that used to record file data when parsing FDF +# +# May raise Exception when opening file. +# +class FileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + + self.PcdDict = {} + self.InfList = [] + + self.FdDict = {} + self.FvDict = {} + self.CapsuleList = [] + self.VtfList = [] + self.RuleDict = {} + self.OptRomDict = {} + +## The syntax parser for FDF +# +# PreprocessFile method should be called prior to ParseFile +# CycleReferenceCheck method can detect cycles in FDF contents +# +# GetNext*** procedures mean these procedures will get next token first, then make judgement. +# Get*** procedures mean these procedures will make judgement on current token only. +# +class FdfParser: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.Profile = FileProfile(FileName) + self.FileName = FileName + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + self.CurrentFdName = None + self.CurrentFvName = None + self.__Token = "" + self.__SkippedChars = "" + + self.__WipeOffArea = [] + + ## __IsWhiteSpace() method + # + # Whether char at current FileBufferPos is whitespace + # + # @param self The object pointer + # @param Char The char to test + # @retval True The char is a kind of white space + # @retval False The char is NOT a kind of white space + # + def __IsWhiteSpace(self, Char): + if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): + return True + else: + return False + + ## __SkipWhiteSpace() method + # + # Skip white spaces from current char, return number of chars skipped + # + # @param self The object pointer + # @retval Count The number of chars skipped + # + def __SkipWhiteSpace(self): + Count = 0 + while not self.__EndOfFile(): + Count += 1 + if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB): + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + else: + Count = Count - 1 + return Count + + ## __EndOfFile() method + # + # Judge current buffer pos is at file end + # + # @param self The object pointer + # @retval True Current File buffer position is at file end + # @retval False Current File buffer position is NOT at file end + # + def __EndOfFile(self): + NumberOfLines = len(self.Profile.FileLinesList) + SizeOfLastLine = len(self.Profile.FileLinesList[-1]) + if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: + return True + elif self.CurrentLineNumber > NumberOfLines: + return True + else: + return False + + ## __EndOfLine() method + # + # Judge current buffer pos is at line end + # + # @param self The object pointer + # @retval True Current File buffer position is at line end + # @retval False Current File buffer position is NOT at line end + # + def __EndOfLine(self): + if self.CurrentLineNumber > len(self.Profile.FileLinesList): + return True + SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if self.CurrentOffsetWithinLine >= SizeOfCurrentLine: + return True + else: + return False + + ## Rewind() method + # + # Reset file data buffer to the initial state + # + # @param self The object pointer + # + def Rewind(self): + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + + ## __UndoOneChar() method + # + # Go back one char in the file buffer + # + # @param self The object pointer + # @retval True Successfully go back one char + # @retval False Not able to go back one char as file beginning reached + # + def __UndoOneChar(self): + + if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: + return False + elif self.CurrentOffsetWithinLine == 0: + self.CurrentLineNumber -= 1 + self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1 + else: + self.CurrentOffsetWithinLine -= 1 + return True + + ## __GetOneChar() method + # + # Move forward one char in the file buffer + # + # @param self The object pointer + # + def __GetOneChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + else: + self.CurrentOffsetWithinLine += 1 + + ## __CurrentChar() method + # + # Get the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Current char + # + def __CurrentChar(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] + + ## __NextChar() method + # + # Get the one char pass the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Next char + # + def __NextChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + return self.Profile.FileLinesList[self.CurrentLineNumber][0] + else: + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] + + ## __SetCurrentCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def __SetCurrentCharValue(self, Value): + self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value + + ## __CurrentLine() method + # + # Get the list that contains current line contents + # + # @param self The object pointer + # @retval List current line contents + # + def __CurrentLine(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1] + + def __StringToList(self): + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList] + self.Profile.FileLinesList[-1].append(' ') + + def __ReplaceMacros(self, Str, File, Line): + MacroEnd = 0 + while Str.find('$(', MacroEnd) >= 0: + MacroStart = Str.find('$(', MacroEnd) + if Str.find(')', MacroStart) > 0: + MacroEnd = Str.find(')', MacroStart) + Name = Str[MacroStart + 2 : MacroEnd] + Value = None + if Name in InputMacroDict: + Value = InputMacroDict[Name] + + else: + for Profile in AllMacroList: + if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line: + Value = Profile.MacroValue + + if Value != None: + Str = Str.replace('$(' + Name + ')', Value) + MacroEnd = MacroStart + len(Value) + + else: + raise Warning("Macro not complete", self.FileName, self.CurrentLineNumber) + return Str + + def __ReplaceFragment(self, StartPos, EndPos, Value = ' '): + if StartPos[0] == EndPos[0]: + Offset = StartPos[1] + while Offset <= EndPos[1]: + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + return + + Offset = StartPos[1] + while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + + Line = StartPos[0] + while Line < EndPos[0]: + Offset = 0 + while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[Line][Offset] = Value + Offset += 1 + Line += 1 + + Offset = 0 + while Offset <= EndPos[1]: + self.Profile.FileLinesList[EndPos[0]][Offset] = Value + Offset += 1 + + + ## PreprocessFile() method + # + # Preprocess file contents, replace comments with spaces. + # In the end, rewind the file buffer pointer to the beginning + # BUGBUG: No !include statement processing contained in this procedure + # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] + # + # @param self The object pointer + # + def PreprocessFile(self): + + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + # HashComment in quoted string " " is ignored. + InString = False + + while not self.__EndOfFile(): + + if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment: + InString = not InString + # meet new line, then no longer in a comment for // and '#' + if self.__CurrentChar() == T_CHAR_LF: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + if InComment and HashComment: + InComment = False + HashComment = False + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + # check for // comment + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine(): + InComment = True + DoubleSlashComment = True + # check for '#' comment + elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString: + InComment = True + HashComment = True + # check for /* comment start + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + InComment = True + else: + self.__GetOneChar() + + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessIncludeFile(self): + + while self.__GetNextToken(): + + if self.__Token == '!include': + IncludeLine = self.CurrentLineNumber + IncludeOffset = self.CurrentOffsetWithinLine - len('!include') + if not self.__GetNextToken(): + raise Warning("expected include file name", self.FileName, self.CurrentLineNumber) + IncFileName = self.__Token + if not os.path.isabs(IncFileName): + if IncFileName.startswith('$(WORKSPACE)'): + Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE')) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + IncFileName = Str + else: + # file is in the same dir with FDF file + FullFdf = self.FileName + if not os.path.isabs(self.FileName): + FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName) + + IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName) + + if not os.path.exists(os.path.normpath(IncFileName)): + raise Warning("Include file not exists", self.FileName, self.CurrentLineNumber) + + IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName)) + + CurrentLine = self.CurrentLineNumber + CurrentOffset = self.CurrentOffsetWithinLine + # list index of the insertion, note that line number is 'CurrentLine + 1' + InsertAtLine = CurrentLine + IncFileProfile.InsertStartLineNumber = InsertAtLine + 1 + # deal with remaining portions after "!include filename", if exists. + if self.__GetNextToken(): + if self.CurrentLineNumber == CurrentLine: + RemainingLine = self.__CurrentLine()[CurrentOffset:] + self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine) + IncFileProfile.InsertAdjust += 1 + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + for Line in IncFileProfile.FileLinesList: + self.Profile.FileLinesList.insert(InsertAtLine, Line) + self.CurrentLineNumber += 1 + InsertAtLine += 1 + + IncludeFileList.append(IncFileProfile) + + # comment out the processed include file statement + TempList = list(self.Profile.FileLinesList[IncludeLine - 1]) + TempList.insert(IncludeOffset, '#') + self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList) + + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessConditionalStatement(self): + # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined] + IfList = [] + while self.__GetNextToken(): + if self.__Token == 'DEFINE': + DefineLine = self.CurrentLineNumber - 1 + DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE') + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + pass + Value = self.__Token + if not Macro in InputMacroDict: + FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!ifdef', '!ifndef', '!if'): + IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + IfList.append([IfStartPos, None, None]) + CondLabel = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + NotDefineFlag = False + if CondLabel == '!ifndef': + NotDefineFlag = True + if CondLabel == '!ifdef' or CondLabel == '!ifndef': + if NotFlag: + raise Warning("'NOT' operation not allowed for Macro name", self.FileName, self.CurrentLineNumber) + + if CondLabel == '!if': + + if not self.__GetNextOp(): + raise Warning("expected !endif", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + else: + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1) + if NotDefineFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!elseif', '!else'): + ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + if len(IfList) <= 0: + raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) + if IfList[-1][1]: + IfList[-1] = [ElseStartPos, False, True] + self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], ElseStartPos)) + IfList[-1] = [ElseStartPos, True, IfList[-1][2]] + if self.__Token == '!elseif': + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + if not self.__GetNextOp(): + raise Warning("expected !endif", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]] + + if IfList[-1][1]: + if IfList[-1][2]: + IfList[-1][1] = False + else: + IfList[-1][2] = True + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + + elif self.__Token == '!endif': + if IfList[-1][1]: + self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + IfList.pop() + + + if len(IfList) > 0: + raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber) + self.Rewind() + + def __EvaluateConditional(self, Name, Line, Op = None, Value = None): + + FileLineTuple = GetRealFileLine(self.FileName, Line) + if Name in InputMacroDict: + MacroValue = InputMacroDict[Name] + if Op == None: + if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != MacroValue: + return True + else: + return False + elif Op == '==': + if Value == MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number", self.FileName, Line) + + for Profile in AllMacroList: + if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]: + if Op == None: + if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != Profile.MacroValue: + return True + else: + return False + elif Op == '==': + if Value == Profile.MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(Profile.MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number", self.FileName, Line) + + return False + + ## __IsToken() method + # + # Check whether input string is found from current char position along + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsToken(self, String, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __IsKeyword() method + # + # Check whether input keyword is found from current char position along, whole word only! + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param Keyword The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsKeyword(self, KeyWord, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord) + if index == 0: + followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)] + if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE: + return False + self.CurrentOffsetWithinLine += len(KeyWord) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __GetNextWord() method + # + # Get next C name from file lines + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a C name string, file buffer pointer moved forward + # @retval False Not able to find a C name string, file buffer pointer not changed + # + def __GetNextWord(self): + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + + TempChar = self.__CurrentChar() + StartPos = self.CurrentOffsetWithinLine + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_': + self.__GetOneChar() + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ + or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-': + self.__GetOneChar() + + else: + break + + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + + return False + + ## __GetNextToken() method + # + # Get next token unit before a seperator + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a token unit, file buffer pointer moved forward + # @retval False Not able to find a token unit, file buffer pointer not changed + # + def __GetNextToken(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + StartLine = self.CurrentLineNumber + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE: + self.__GetOneChar() + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + self.__GetOneChar() + break + else: + break +# else: +# return False + + EndPos = self.CurrentOffsetWithinLine + if self.CurrentLineNumber != StartLine: + EndPos = len(self.Profile.FileLinesList[StartLine-1]) + self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos] + if StartPos != self.CurrentOffsetWithinLine: + return True + else: + return False + + def __GetNextOp(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space + if not str(TempChar).isspace(): + self.__GetOneChar() + else: + break + else: + return False + + if StartPos != self.CurrentOffsetWithinLine: + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + else: + return False + ## __GetNextGuid() method + # + # Get next token unit before a seperator + # If found, the GUID string is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a registry format GUID, file buffer pointer moved forward + # @retval False Not able to find a registry format GUID, file buffer pointer not changed + # + def __GetNextGuid(self): + + if not self.__GetNextToken(): + return False + p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') + if p.match(self.__Token) != None: + return True + else: + self.__UndoToken() + return False + + ## __UndoToken() method + # + # Go back one token unit in file buffer + # + # @param self The object pointer + # + def __UndoToken(self): + self.__UndoOneChar() + while self.__CurrentChar().isspace(): + if not self.__UndoOneChar(): + self.__GetOneChar() + return + + + StartPos = self.CurrentOffsetWithinLine + CurrentLine = self.CurrentLineNumber + while CurrentLine == self.CurrentLineNumber: + + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE: + if not self.__UndoOneChar(): + break + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + return + else: + break + + self.__GetOneChar() + + ## __HexDigit() method + # + # Whether char input is a Hex data bit + # + # @param self The object pointer + # @param TempChar The char to test + # @retval True The char is a Hex data bit + # @retval False The char is NOT a Hex data bit + # + def __HexDigit(self, TempChar): + if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \ + or (TempChar >= '0' and TempChar <= '9'): + return True + else: + return False + + def __IsHex(self, HexStr): + if not HexStr.upper().startswith("0X"): + return False + if len(self.__Token) <= 2: + return False + charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)] + if len(charList) == 0: + return True + else: + return False + ## __GetNextHexNumber() method + # + # Get next HEX data before a seperator + # If found, the HEX data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a HEX data, file buffer pointer moved forward + # @retval False Not able to find a HEX data, file buffer pointer not changed + # + def __GetNextHexNumber(self): + if not self.__GetNextToken(): + return False + if self.__IsHex(self.__Token): + return True + else: + self.__UndoToken() + return False + + ## __GetNextDecimalNumber() method + # + # Get next decimal data before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a decimal data, file buffer pointer moved forward + # @retval False Not able to find a decimal data, file buffer pointer not changed + # + def __GetNextDecimalNumber(self): + if not self.__GetNextToken(): + return False + if self.__Token.isdigit(): + return True + else: + self.__UndoToken() + return False + + ## __GetNextPcdName() method + # + # Get next PCD token space C name and PCD C name pair before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval Tuple PCD C name and PCD token space C name pair + # + def __GetNextPcdName(self): + if not self.__GetNextWord(): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + pcdTokenSpaceCName = self.__Token + + if not self.__IsToken( "."): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + pcdCName = self.__Token + + return (pcdCName, pcdTokenSpaceCName) + + ## __GetStringData() method + # + # Get string contents quoted in "" + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a string data, file buffer pointer moved forward + # @retval False Not able to find a string data, file buffer pointer not changed + # + def __GetStringData(self): + if self.__Token.startswith("\"") or self.__Token.startswith("L\""): + self.__UndoToken() + self.__SkipToToken("\"") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\""): + raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\"') + return True + + elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"): + self.__UndoToken() + self.__SkipToToken("\'") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\'"): + raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\'') + return True + + else: + return False + + ## __SkipToToken() method + # + # Search forward in file buffer for the string + # The skipped chars are put into self.__SkippedChars + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find the string, file buffer pointer moved forward + # @retval False Not able to find the string, file buffer pointer not changed + # + def __SkipToToken(self, String, IgnoreCase = False): + StartPos = self.GetFileBufferPos() + + self.__SkippedChars = "" + while not self.__EndOfFile(): + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__SkippedChars += String + return True + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + self.SetFileBufferPos( StartPos) + self.__SkippedChars = "" + return False + + ## GetFileBufferPos() method + # + # Return the tuple of current line and offset within the line + # + # @param self The object pointer + # @retval Tuple Line number and offset pair + # + def GetFileBufferPos(self): + return (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + ## SetFileBufferPos() method + # + # Restore the file buffer position + # + # @param self The object pointer + # @param Pos The new file buffer position + # + def SetFileBufferPos(self, Pos): + (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos + + ## ParseFile() method + # + # Parse the file profile buffer to extract fd, fv ... information + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def ParseFile(self): + + try: + self.__StringToList() + self.PreprocessFile() + self.PreprocessIncludeFile() + self.__StringToList() + self.PreprocessFile() + self.PreprocessConditionalStatement() + self.__StringToList() + for Pos in self.__WipeOffArea: + self.__ReplaceFragment(Pos[0], Pos[1]) + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + + while self.__GetDefines(): + pass + + Index = 0 + while Index < len(self.Profile.FileLinesList): + FileLineTuple = GetRealFileLine(self.FileName, Index + 1) + self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1]) + Index += 1 + + while self.__GetFd(): + pass + + while self.__GetFv(): + pass + + while self.__GetCapsule(): + pass + + while self.__GetVtf(): + pass + + while self.__GetRule(): + pass + + while self.__GetOptionRom(): + pass + + except Warning, X: + self.__UndoToken() + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \ + X.Message += ' near line %d, column %d: %s' \ + % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r')) + raise + + ## __GetDefines() method + # + # Get Defines section contents and store its data into AllMacrosList + # + # @param self The object pointer + # @retval True Successfully find a Defines + # @retval False Not able to find a Defines + # + def __GetDefines(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[DEFINES"): + if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[DEFINES", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + while self.__GetNextWord(): + Macro = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken() or self.__Token.startswith('['): + raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber) + Value = self.__Token + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + + return False + + ## __GetFd() method + # + # Get FD section contents and store its data into FD dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FD + # @retval False Not able to find a FD + # + def __GetFd(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FD."): + if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FD.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber) + + FdName = self.__GetUiName() + self.CurrentFdName = FdName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + FdObj = Fd.FD() + FdObj.FdUiName = self.CurrentFdName + self.Profile.FdDict[self.CurrentFdName] = FdObj + Status = self.__GetCreateFile(FdObj) + if not Status: + raise Warning("FD name error", self.FileName, self.CurrentLineNumber) + + if not self.__GetTokenStatements(FdObj): + return False + + self.__GetDefineStatements(FdObj) + + self.__GetSetStatements(FdObj) + + if not self.__GetRegionLayout(FdObj): + raise Warning("expected region layout", self.FileName, self.CurrentLineNumber) + + while self.__GetRegionLayout(FdObj): + pass + return True + + ## __GetUiName() method + # + # Return the UI name of a section + # + # @param self The object pointer + # @retval FdName UI name + # + def __GetUiName(self): + Name = "" + if self.__GetNextWord(): + Name = self.__Token + + return Name + + ## __GetCreateFile() method + # + # Return the output file name of object + # + # @param self The object pointer + # @param Obj object whose data will be stored in file + # @retval FdName UI name + # + def __GetCreateFile(self, Obj): + + if self.__IsKeyword( "CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name", self.FileName, self.CurrentLineNumber) + + FileName = self.__Token + Obj.CreateFileName = FileName + + return True + + ## __GetTokenStatements() method + # + # Get token statements + # + # @param self The object pointer + # @param Obj for whom token statement is got + # @retval True Successfully find a token statement + # @retval False Not able to find a token statement + # + def __GetTokenStatements(self, Obj): + if not self.__IsKeyword( "BaseAddress"): + raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber) + + Obj.BaseAddress = self.__Token + + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.BaseAddressPcd = pcdPair + self.Profile.PcdDict[pcdPair] = Obj.BaseAddress + + if not self.__IsKeyword( "Size"): + raise Warning("Size missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber) + + + Size = self.__Token + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.SizePcd = pcdPair + self.Profile.PcdDict[pcdPair] = Size + Obj.Size = long(Size, 0) + + if not self.__IsKeyword( "ErasePolarity"): + raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber) + + if self.__Token != "1" and self.__Token != "0": + raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber) + + Obj.ErasePolarity = self.__Token + + Status = self.__GetBlockStatements(Obj) + return Status + + ## __GetAddressStatements() method + # + # Get address statements + # + # @param self The object pointer + # @param Obj for whom address statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetAddressStatements(self, Obj): + + if self.__IsKeyword("BsBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address", self.FileName, self.CurrentLineNumber) + + BsAddress = long(self.__Token, 0) + Obj.BsBaseAddress = BsAddress + + if self.__IsKeyword("RtBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address", self.FileName, self.CurrentLineNumber) + + RtAddress = long(self.__Token, 0) + Obj.RtBaseAddress = RtAddress + + ## __GetBlockStatements() method + # + # Get block statements + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatements(self, Obj): + + if not self.__GetBlockStatement(Obj): + raise Warning("expected block statement", self.FileName, self.CurrentLineNumber) + + while self.__GetBlockStatement(Obj): + pass + return True + + ## __GetBlockStatement() method + # + # Get block statement + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatement(self, Obj): + if not self.__IsKeyword( "BlockSize"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber(): + raise Warning("expected Hex block size", self.FileName, self.CurrentLineNumber) + + BlockSize = self.__Token + BlockSizePcd = None + if self.__IsToken( "|"): + PcdPair = self.__GetNextPcdName() + BlockSizePcd = PcdPair + self.Profile.PcdDict[PcdPair] = BlockSize + BlockSize = long(self.__Token, 0) + + BlockNumber = None + if self.__IsKeyword( "NumBlocks"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber) + + BlockNumber = long(self.__Token, 0) + + Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd)) + return True + + ## __GetDefineStatements() method + # + # Get define statements + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatements(self, Obj): + while self.__GetDefineStatement( Obj): + pass + + ## __GetDefineStatement() method + # + # Get define statement + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatement(self, Obj): + if self.__IsKeyword("DEFINE"): + self.__GetNextToken() + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + Macro = '$(' + Macro + ')' + Obj.DefineVarDict[Macro] = Value + return True + + return False + + ## __GetSetStatements() method + # + # Get set statements + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatements(self, Obj): + while self.__GetSetStatement(Obj): + pass + + ## __GetSetStatement() method + # + # Get set statement + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatement(self, Obj): + if self.__IsKeyword("SET"): + PcdPair = self.__GetNextPcdName() + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + if Value.startswith("{"): + # deal with value with {} + if not self.__SkipToToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Value += self.__SkippedChars + + Obj.SetVarDict[PcdPair] = Value + self.Profile.PcdDict[PcdPair] = Value + return True + + return False + + ## __GetRegionLayout() method + # + # Get region layout for FD + # + # @param self The object pointer + # @param Fd for whom region is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetRegionLayout(self, Fd): + if not self.__GetNextHexNumber(): + return False + + RegionObj = Region.Region() + RegionObj.Offset = long(self.__Token, 0) + Fd.RegionList.append(RegionObj) + + if not self.__IsToken( "|"): + raise Warning("expected '|'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber) + RegionObj.Size = long(self.__Token, 0) + + if not self.__GetNextWord(): + return True + + if not self.__Token in ("SET", "FV", "FILE", "DATA"): + self.__UndoToken() + RegionObj.PcdOffset = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0)) + if self.__IsToken( "|"): + RegionObj.PcdSize = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size + + if not self.__GetNextWord(): + return True + + if self.__Token == "SET": + self.__UndoToken() + self.__GetSetStatements( RegionObj) + if not self.__GetNextWord(): + return True + + if self.__Token == "FV": + self.__UndoToken() + self.__GetRegionFvType( RegionObj) + + elif self.__Token == "FILE": + self.__UndoToken() + self.__GetRegionFileType( RegionObj) + + else: + self.__UndoToken() + self.__GetRegionDataType( RegionObj) + + return True + + ## __GetRegionFvType() method + # + # Get region fv data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFvType(self, RegionObj): + + if not self.__IsKeyword( "FV"): + raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FV" + RegionObj.RegionDataList.append(self.__Token) + + while self.__IsKeyword( "FV"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionFileType() method + # + # Get region file data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFileType(self, RegionObj): + + if not self.__IsKeyword( "FILE"): + raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FILE" + RegionObj.RegionDataList.append( self.__Token) + + while self.__IsKeyword( "FILE"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionDataType() method + # + # Get region array data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionDataType(self, RegionObj): + + if not self.__IsKeyword( "DATA"): + raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + if not self.__GetNextHexNumber(): + raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionType = "DATA" + RegionObj.RegionDataList.append( DataString) + + while self.__IsKeyword( "DATA"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + self.__GetNextHexNumber() + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionDataList.append( DataString) + + ## __GetFv() method + # + # Get FV section contents and store its data into FV dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FV + # @retval False Not able to find a FV + # + def __GetFv(self): + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FV."): + if not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FV.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + FvName = self.__GetUiName() + self.CurrentFvName = FvName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + FvObj = Fv.FV() + FvObj.UiFvName = self.CurrentFvName + self.Profile.FvDict[self.CurrentFvName] = FvObj + + Status = self.__GetCreateFile(FvObj) + if not Status: + raise Warning("FV name error", self.FileName, self.CurrentLineNumber) + + self.__GetDefineStatements(FvObj) + + self.__GetAddressStatements(FvObj) + + self.__GetBlockStatement(FvObj) + + self.__GetSetStatements(FvObj) + + self.__GetFvAlignment(FvObj) + + self.__GetFvAttributes(FvObj) + + self.__GetFvNameGuid(FvObj) + + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + + while True: + isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + if not isInf and not isFile: + break + + return True + + ## __GetFvAlignment() method + # + # Get alignment for FV + # + # @param self The object pointer + # @param Obj for whom alignment is got + # @retval True Successfully find a alignment statement + # @retval False Not able to find a alignment statement + # + def __GetFvAlignment(self, Obj): + + if not self.__IsKeyword( "FvAlignment"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) + + if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \ + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \ + "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \ + "1G", "2G"): + raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + Obj.FvAlignment = self.__Token + return True + + ## __GetFvAttributes() method + # + # Get attributes for FV + # + # @param self The object pointer + # @param Obj for whom attribute is got + # @retval None + # + def __GetFvAttributes(self, FvObj): + + while self.__GetNextWord(): + name = self.__Token + if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \ + "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \ + "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \ + "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \ + "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \ + "WRITE_POLICY_RELIABLE"): + self.__UndoToken() + return + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + + FvObj.FvAttributeDict[name] = self.__Token + + return + + ## __GetFvNameGuid() method + # + # Get FV GUID for FV + # + # @param self The object pointer + # @param Obj for whom GUID is got + # @retval None + # + def __GetFvNameGuid(self, FvObj): + + if not self.__IsKeyword( "FvNameGuid"): + return + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber) + + FvObj.FvNameGuid = self.__Token + + return + + ## __GetAprioriSection() method + # + # Get token statements + # + # @param self The object pointer + # @param FvObj for whom apriori is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find apriori statement + # @retval False Not able to find apriori statement + # + def __GetAprioriSection(self, FvObj, MacroDict = {}): + + if not self.__IsKeyword( "APRIORI"): + return False + + if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"): + raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber) + AprType = self.__Token + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + AprSectionObj = AprioriSection.AprioriSection() + AprSectionObj.AprioriType = AprType + + self.__GetDefineStatements(AprSectionObj) + MacroDict.update(AprSectionObj.DefineVarDict) + + while True: + IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict) + IsFile = self.__GetFileStatement( AprSectionObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + FvObj.AprioriSectionList.append(AprSectionObj) + return True + + ## __GetInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "INF"): + return False + + ffsInf = FfsInfStatement.FfsInfStatement() + self.__GetInfOptions( ffsInf) + + if not self.__GetNextToken(): + raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self.__Token + +# if ffsInf.InfFileName.find('$') >= 0: +# ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict) + + if not ffsInf.InfFileName in self.Profile.InfList: + self.Profile.InfList.append(ffsInf.InfFileName) + + if self.__IsToken('|'): + if self.__IsKeyword('RELOCS_STRIPPED'): + ffsInf.KeepReloc = False + elif self.__IsKeyword('RELOCS_RETAINED'): + ffsInf.KeepReloc = True + else: + raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = ffsInf + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(ffsInf) + return True + + ## __GetInfOptions() method + # + # Get options for INF + # + # @param self The object pointer + # @param FfsInfObj for whom option is got + # + def __GetInfOptions(self, FfsInfObj): + + if self.__IsKeyword( "RuleOverride"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber) + FfsInfObj.Rule = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Version", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Version = self.__Token + + if self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI name", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Ui = self.__Token + + if self.__IsKeyword( "USE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber) + FfsInfObj.UseArch = self.__Token + + + if self.__GetNextToken(): + p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if p.match(self.__Token): + FfsInfObj.KeyStringList.append(self.__Token) + if not self.__IsToken(","): + return + else: + self.__UndoToken() + return + + while self.__GetNextToken(): + if not p.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsInfObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + ## __GetFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "FILE"): + return False + + FfsFileObj = FfsFileStatement.FileStatement() + + if not self.__GetNextWord(): + raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvFileType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + if not self.__GetNextWord(): + raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + FfsFileObj.NameGuid = self.__Token + + self.__GetFilePart( FfsFileObj, MacroDict.copy()) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = FfsFileObj + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(FfsFileObj) + + return True + + ## __FileCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a file type. + # + # @param self The object pointer + # @param FileType The file type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __FileCouldHaveRelocFlag (self, FileType): + if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'): + return True + else: + return False + + ## __SectionCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a section type. + # + # @param self The object pointer + # @param SectionType The section type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __SectionCouldHaveRelocFlag (self, SectionType): + if SectionType in ('TE', 'PE32'): + return True + else: + return False + + ## __GetFilePart() method + # + # Get components for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom component is got + # @param MacroDict dictionary used to replace macro + # + def __GetFilePart(self, FfsFileObj, MacroDict = {}): + + self.__GetFileOpts( FfsFileObj) + + if not self.__IsToken("{"): +# if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): +# if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType): +# if self.__Token == 'RELOCS_STRIPPED': +# FfsFileObj.KeepReloc = False +# else: +# FfsFileObj.KeepReloc = True +# else: +# raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) +# +# if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber) + + if self.__Token == "FV": + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvName = self.__Token + + elif self.__Token == "FD": + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FD name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FdName = self.__Token + + elif self.__Token in ("DEFINE", "APRIORI", "SECTION"): + self.__UndoToken() + self.__GetSectionData( FfsFileObj, MacroDict) + else: + FfsFileObj.FileName = self.__Token + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + ## __GetFileOpts() method + # + # Get options for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom options is got + # + def __GetFileOpts(self, FfsFileObj): + + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + FfsFileObj.KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsFileObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + if self.__IsKeyword( "FIXED", True): + FfsFileObj.Fixed = True + + if self.__IsKeyword( "CHECKSUM", True): + FfsFileObj.CheckSum = True + + if self.__GetAlignment(): + FfsFileObj.Alignment = self.__Token + + + + ## __GetAlignment() method + # + # Return the alignment value + # + # @param self The object pointer + # @retval True Successfully find alignment + # @retval False Not able to find alignment + # + def __GetAlignment(self): + if self.__IsKeyword( "Align", True): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) + return True + + return False + + ## __GetFilePart() method + # + # Get section data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # @param MacroDict dictionary used to replace macro + # + def __GetSectionData(self, FfsFileObj, MacroDict = {}): + Dict = {} + Dict.update(MacroDict) + + self.__GetDefineStatements(FfsFileObj) + + Dict.update(FfsFileObj.DefineVarDict) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + + while True: + IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict) + IsEncapSection = self.__GetEncapsulationSec(FfsFileObj) + if not IsLeafSection and not IsEncapSection: + break + + ## __GetLeafSection() method + # + # Get leaf section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetLeafSection(self, Obj, MacroDict = {}): + + OldPos = self.GetFileBufferPos() + + if not self.__IsKeyword( "SECTION"): + if len(Obj.SectionList) == 0: + raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + BuildNum = None + if self.__IsKeyword( "BUILD_NUM"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber) + + BuildNum = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected version", self.FileName, self.CurrentLineNumber) + VerSectionObj = VerSection.VerSection() + VerSectionObj.Alignment = AlignValue + VerSectionObj.BuildNum = BuildNum + if self.__GetStringData(): + VerSectionObj.StringData = self.__Token + else: + VerSectionObj.FileName = self.__Token + Obj.SectionList.append(VerSectionObj) + + elif self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI", self.FileName, self.CurrentLineNumber) + UiSectionObj = UiSection.UiSection() + UiSectionObj.Alignment = AlignValue + if self.__GetStringData(): + UiSectionObj.StringData = self.__Token + else: + UiSectionObj.FileName = self.__Token + Obj.SectionList.append(UiSectionObj) + + elif self.__IsKeyword( "FV_IMAGE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber) + + FvName = self.__Token + FvObj = None + + if self.__IsToken( "{"): + FvObj = Fv.FV() + FvObj.UiFvName = FvName.upper() + self.__GetDefineStatements(FvObj) + MacroDict.update(FvObj.DefineVarDict) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + + while True: + IsInf = self.__GetInfStatement(FvObj, MacroDict.copy()) + IsFile = self.__GetFileStatement(FvObj, MacroDict.copy()) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + FvImageSectionObj = FvImageSection.FvImageSection() + FvImageSectionObj.Alignment = AlignValue + if FvObj != None: + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + else: + FvImageSectionObj.FvName = FvName.upper() + FvImageSectionObj.FvFileName = FvName + + Obj.SectionList.append(FvImageSectionObj) + + elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"): + DepexSectionObj = DepexSection.DepexSection() + DepexSectionObj.Alignment = AlignValue + DepexSectionObj.DepexType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + if not self.__SkipToToken( "}"): + raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber) + + DepexSectionObj.Expression = self.__SkippedChars.rstrip('}') + Obj.SectionList.append(DepexSectionObj) + + else: + + if not self.__GetNextWord(): + raise Warning("expected section type", self.FileName, self.CurrentLineNumber) + + # Encapsulation section appear, UndoToken and return + if self.__Token == "COMPRESS" or self.__Token == "GUIDED": + self.SetFileBufferPos(OldPos) + return False + + if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + # DataSection + DataSectionObj = DataSection.DataSection() + DataSectionObj.Alignment = AlignValue + DataSectionObj.SecType = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType): + if self.__Token == 'RELOCS_STRIPPED': + DataSectionObj.KeepReloc = False + else: + DataSectionObj.KeepReloc = True + else: + raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if self.__IsToken("="): + if not self.__GetNextToken(): + raise Warning("expected section file path", self.FileName, self.CurrentLineNumber) + DataSectionObj.SectFileName = self.__Token + else: + if not self.__GetCglSection(DataSectionObj): + return False + + Obj.SectionList.append(DataSectionObj) + + return True + + ## __GetCglSection() method + # + # Get compressed or GUIDed section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param AlignValue alignment value for complex section + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetCglSection(self, Obj, AlignValue = None): + + if self.__IsKeyword( "COMPRESS"): + type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection.CompressSection() + CompressSectionObj.Alignment = AlignValue + CompressSectionObj.CompType = type + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(CompressSectionObj) + IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(CompressSectionObj) + +# else: +# raise Warning("Compress type not known") + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection.GuidSection() + GuidSectionObj.Alignment = AlignValue + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(GuidSectionObj) + IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetGuidAttri() method + # + # Get attributes for GUID section + # + # @param self The object pointer + # @retval AttribDict Dictionary of key-value pair of section attributes + # + def __GetGuidAttrib(self): + + AttribDict = {} + AttribDict["PROCESSING_REQUIRED"] = False + AttribDict["AUTH_STATUS_VALID"] = False + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='") + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + return AttribDict + + ## __GetEncapsulationSec() method + # + # Get encapsulation section for FILE + # + # @param self The object pointer + # @param FfsFile for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEncapsulationSec(self, FfsFileObj): + + OldPos = self.GetFileBufferPos() + if not self.__IsKeyword( "SECTION"): + if len(FfsFileObj.SectionList) == 0: + raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + if not self.__GetCglSection(FfsFileObj, AlignValue): + self.SetFileBufferPos(OldPos) + return False + else: + return True + + ## __GetCapsule() method + # + # Get capsule section contents and store its data into capsule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a capsule + # @retval False Not able to find a capsule + # + def __GetCapsule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[CAPSULE."): + if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[CAPSULE.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber) + + CapsuleObj = Capsule.Capsule() + + CapsuleName = self.__GetUiName() + if not CapsuleName: + raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.UiCapsuleName = CapsuleName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.CreateFile = self.__Token + + self.__GetCapsuleStatements(CapsuleObj) + self.Profile.CapsuleList.append(CapsuleObj) + return True + + ## __GetCapsuleStatements() method + # + # Get statements for capsule + # + # @param self The object pointer + # @param Obj for whom statements are got + # + def __GetCapsuleStatements(self, Obj): + self.__GetCapsuleTokens(Obj) + self.__GetDefineStatements(Obj) + self.__GetSetStatements(Obj) + + self.__GetCapsuleData(Obj) + + ## __GetCapsuleStatements() method + # + # Get token statements for capsule + # + # @param self The object pointer + # @param Obj for whom token statements are got + # + def __GetCapsuleTokens(self, Obj): + + if not self.__IsKeyword("CAPSULE_GUID"): + raise Warning("expected 'CAPSULE_GUID'", self.FileName, self.CurrentLineNumber) + + while self.__CurrentLine().find("=") != -1: + NameValue = self.__CurrentLine().split("=") + Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip() + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + ## __GetCapsuleData() method + # + # Get capsule data for capsule + # + # @param self The object pointer + # @param Obj for whom capsule data are got + # + def __GetCapsuleData(self, Obj): + + while True: + IsInf = self.__GetInfStatement(Obj, True) + IsFile = self.__GetFileStatement(Obj, True) + IsFv = self.__GetFvStatement(Obj) + if not IsInf and not IsFile and not IsFv: + break + + ## __GetFvStatement() method + # + # Get FV for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom FV is got + # @retval True Successfully find a FV statement + # @retval False Not able to find a FV statement + # + def __GetFvStatement(self, CapsuleObj): + + if not self.__IsKeyword("FV"): + return False + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + CapsuleFv = CapsuleData.CapsuleFv() + CapsuleFv.FvName = self.__Token + CapsuleObj.CapsuleDataList.append(CapsuleFv) + return True + + ## __GetRule() method + # + # Get Rule section contents and store its data into rule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a Rule + # @retval False Not able to find a Rule + # + def __GetRule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[RULE."): + if not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + self.__UndoToken() + if not self.__IsToken("[Rule.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".") + if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"): + raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) + + ModuleType = self.__GetModuleType() + + TemplateName = "" + if self.__IsToken("."): + if not self.__GetNextWord(): + raise Warning("expected template name", self.FileName, self.CurrentLineNumber) + TemplateName = self.__Token + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + RuleObj = self.__GetRuleFileStatements() + RuleObj.Arch = Arch.upper() + RuleObj.ModuleType = ModuleType + RuleObj.TemplateName = TemplateName + if TemplateName == '' : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() ] = RuleObj + else : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() + \ + '.' + \ + TemplateName.upper() ] = RuleObj +# self.Profile.RuleList.append(rule) + return True + + ## __GetModuleType() method + # + # Return the module type + # + # @param self The object pointer + # @retval string module type + # + def __GetModuleType(self): + + if not self.__GetNextWord(): + raise Warning("expected Module type", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \ + "DXE_DRIVER", "DXE_SAL_DRIVER", \ + "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \ + "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \ + "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \ + "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_DRIVER", "SMM_CORE"): + raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + return self.__Token + + ## __GetFileExtension() method + # + # Return the file extension + # + # @param self The object pointer + # @retval string file name extension + # + def __GetFileExtension(self): + if not self.__IsToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Ext = "" + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') + if Pattern.match(self.__Token): + Ext = self.__Token + return '.' + Ext + else: + raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + else: + raise Warning("expected file extension", self.FileName, self.CurrentLineNumber) + + ## __GetRuleFileStatement() method + # + # Get rule contents + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRuleFileStatements(self): + + if not self.__IsKeyword("FILE"): + raise Warning("expected FILE", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) + + Type = self.__Token.strip().upper() + if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\ + "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM_DXE_COMBO", "SMM", "SMM_CORE"): + raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsKeyword("$(NAMED_GUID)"): + if not self.__GetNextWord(): + raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + NameGuid = self.__Token + + KeepReloc = None + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Type): + if self.__Token == 'RELOCS_STRIPPED': + KeepReloc = False + else: + KeepReloc = True + else: + raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + KeyStringList = [] + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + + Fixed = False + if self.__IsKeyword("Fixed", True): + Fixed = True + + CheckSum = False + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + AlignValue = "" + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if self.__IsToken("{"): + # Complex file rule expected + Rule = RuleComplexFile.RuleComplexFile() + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(Rule) + IsLeaf = self.__GetEfiSection(Rule) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken("}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + return Rule + + elif self.__IsToken("|"): + # Ext rule expected + Ext = self.__GetFileExtension() + + Rule = RuleSimpleFile.RuleSimpleFile() + + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileExtension = Ext + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + return Rule + + else: + # Simple file rule expected + if not self.__GetNextWord(): + raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber) + + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber) + + + if self.__IsKeyword("Fixed", True): + Fixed = True + + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected File name", self.FileName, self.CurrentLineNumber) + + Rule = RuleSimpleFile.RuleSimpleFile() + Rule.SectionType = SectionName + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileName = self.__Token + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + return Rule + + ## __GetEfiSection() method + # + # Get section list for Rule + # + # @param self The object pointer + # @param Obj for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEfiSection(self, Obj): + + OldPos = self.GetFileBufferPos() + if not self.__GetNextWord(): + return False + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + self.__UndoToken() + return False + + if SectionName == "FV_IMAGE": + FvImageSectionObj = FvImageSection.FvImageSection() + if self.__IsKeyword("FV_IMAGE"): + pass + if self.__IsToken( "{"): + FvObj = Fv.FV() + self.__GetDefineStatements(FvObj) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj) + self.__GetAprioriSection(FvObj) + + while True: + IsInf = self.__GetInfStatement(FvObj) + IsFile = self.__GetFileStatement(FvObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + + else: + if not self.__IsKeyword("FV"): + raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsKeyword("FV"): + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsToken('|'): + FvImageSectionObj.FvFileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + FvImageSectionObj.FvFileName = self.__Token + else: + self.__UndoToken() + else: + raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(FvImageSectionObj) + return True + + EfiSectionObj = EfiSection.EfiSection() + EfiSectionObj.SectionType = SectionName + + if not self.__GetNextToken(): + raise Warning("expected file type", self.FileName, self.CurrentLineNumber) + + if self.__Token == "STRING": + if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken('='): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + EfiSectionObj.StringData = self.__Token + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + else: + EfiSectionObj.FileType = self.__Token + self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType) + + if self.__IsKeyword("Optional"): + if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType): + raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + EfiSectionObj.Optional = True + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + if self.__GetAlignment(): + EfiSectionObj.Alignment = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType): + if self.__Token == 'RELOCS_STRIPPED': + EfiSectionObj.KeepReloc = False + else: + EfiSectionObj.KeepReloc = True + if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc: + raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + else: + raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + + + if self.__IsToken('|'): + EfiSectionObj.FileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + + if self.__Token.startswith('PCD'): + self.__UndoToken() + self.__GetNextWord() + + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + EfiSectionObj.FileName = self.__Token + + else: + self.__UndoToken() + else: + raise Warning("expected section file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(EfiSectionObj) + return True + + ## __RuleSectionCouldBeOptional() method + # + # Get whether a section could be optional + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could be optional + # @retval False section never optional + # + def __RuleSectionCouldBeOptional(self, SectionType): + if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"): + return True + else: + return False + + ## __RuleSectionCouldHaveBuildNum() method + # + # Get whether a section could have build number information + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have build number information + # @retval False section never have build number information + # + def __RuleSectionCouldHaveBuildNum(self, SectionType): + if SectionType in ("VERSION"): + return True + else: + return False + + ## __RuleSectionCouldHaveString() method + # + # Get whether a section could have string + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have string + # @retval False section never have string + # + def __RuleSectionCouldHaveString(self, SectionType): + if SectionType in ("UI", "VERSION"): + return True + else: + return False + + ## __CheckRuleSectionFileType() method + # + # Get whether a section matches a file type + # + # @param self The object pointer + # @param SectionType The section type to check + # @param FileType The file type to check + # + def __CheckRuleSectionFileType(self, SectionType, FileType): + if SectionType == "COMPAT16": + if FileType not in ("COMPAT16", "SEC_COMPAT16"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PE32": + if FileType not in ("PE32", "SEC_PE32"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PIC": + if FileType not in ("PIC", "PIC"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "TE": + if FileType not in ("TE", "SEC_TE"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "RAW": + if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "DXE_DEPEX": + if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "UI": + if FileType not in ("UI", "SEC_UI"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "VERSION": + if FileType not in ("VERSION", "SEC_VERSION"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PEI_DEPEX": + if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "GUID": + if FileType not in ("PE32", "SEC_GUID"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + + ## __GetRuleEncapsulationSection() method + # + # Get encapsulation section for Rule + # + # @param self The object pointer + # @param Rule for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetRuleEncapsulationSection(self, Rule): + + if self.__IsKeyword( "COMPRESS"): + Type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + Type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection.CompressSection() + + CompressSectionObj.CompType = Type + # Recursive sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj) + IsLeaf = self.__GetEfiSection(CompressSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(CompressSectionObj) + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + if self.__IsKeyword( "$(NAMED_GUID)"): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection.GuidSection() + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + + # Efi sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj) + IsLeaf = self.__GetEfiSection(GuidSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetVtf() method + # + # Get VTF section contents and store its data into VTF list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a VTF + # @retval False Not able to find a VTF + # + def __GetVtf(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[VTF."): + if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[VTF.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".").upper() + if Arch not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber) + Name = self.__Token.upper() + + VtfObj = Vtf.Vtf() + VtfObj.UiName = Name + VtfObj.KeyArch = Arch + + if self.__IsToken(","): + if not self.__GetNextWord(): + raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + VtfObj.ArchList = self.__Token.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("IA32_RST_BIN"): + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber) + + VtfObj.ResetBin = self.__Token + + while self.__GetComponentStatement(VtfObj): + pass + + self.Profile.VtfList.append(VtfObj) + return True + + ## __GetComponentStatement() method + # + # Get components in VTF + # + # @param self The object pointer + # @param VtfObj for whom component is got + # @retval True Successfully find a component + # @retval False Not able to find a component + # + def __GetComponentStatement(self, VtfObj): + + if not self.__IsKeyword("COMP_NAME"): + return False + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber) + + CompStatementObj = ComponentStatement.ComponentStatement() + CompStatementObj.CompName = self.__Token + + if not self.__IsKeyword("COMP_LOC"): + raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompLoc = "" + if self.__GetNextWord(): + CompStatementObj.CompLoc = self.__Token + if self.__IsToken('|'): + if not self.__GetNextWord(): + raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber) + + if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support + raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + CompStatementObj.FilePos = self.__Token + else: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + if not self.__IsKeyword("COMP_TYPE"): + raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component type", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"): + if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \ + not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]): + raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompType = self.__Token + + if not self.__IsKeyword("COMP_VER"): + raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component version", self.FileName, self.CurrentLineNumber) + + Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}') + if Pattern.match(self.__Token) == None: + raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompVer = self.__Token + + if not self.__IsKeyword("COMP_CS"): + raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("1", "0"): + raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompCs = self.__Token + + + if not self.__IsKeyword("COMP_BIN"): + raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component file", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompBin = self.__Token + + if not self.__IsKeyword("COMP_SYM"): + raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompSym = self.__Token + + if not self.__IsKeyword("COMP_SIZE"): + raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if self.__IsToken("-"): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextDecimalNumber(): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextHexNumber(): + CompStatementObj.CompSize = self.__Token + else: + raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + VtfObj.ComponentStatementList.append(CompStatementObj) + return True + + ## __GetOptionRom() method + # + # Get OptionROM section contents and store its data into OptionROM list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a OptionROM + # @retval False Not able to find a OptionROM + # + def __GetOptionRom(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + + self.__UndoToken() + if not self.__IsToken("[OptionRom.", True): + raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + OptRomName = self.__GetUiName() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + OptRomObj = OptionRom.OPTIONROM() + OptRomObj.DriverName = OptRomName + self.Profile.OptRomDict[OptRomName] = OptRomObj + + while True: + isInf = self.__GetOptRomInfStatement(OptRomObj) + isFile = self.__GetOptRomFileStatement(OptRomObj) + if not isInf and not isFile: + break + + return True + + ## __GetOptRomInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def __GetOptRomInfStatement(self, Obj): + + if not self.__IsKeyword( "INF"): + return False + + ffsInf = OptRomInfStatement.OptRomInfStatement() + self.__GetInfOptions( ffsInf) + + if not self.__GetNextToken(): + raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self.__Token + + if not ffsInf.InfFileName in self.Profile.InfList: + self.Profile.InfList.append(ffsInf.InfFileName) + + + self.__GetOptRomOverrides (ffsInf) + + Obj.FfsList.append(ffsInf) + return True + + ## __GetOptRomOverrides() method + # + # Get overrides for OptROM INF & FILE + # + # @param self The object pointer + # @param FfsInfObj for whom overrides is got + # + def __GetOptRomOverrides(self, Obj): + if self.__IsToken('{'): + Overrides = OptionRom.OverrideAttribs() + if self.__IsKeyword( "PCI_VENDOR_ID"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber) + Overrides.PciVendorId = self.__Token + + if self.__IsKeyword( "PCI_CLASS_CODE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber) + Overrides.PciClassCode = self.__Token + + if self.__IsKeyword( "PCI_DEVICE_ID"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber) + + Overrides.PciDeviceId = self.__Token + + if self.__IsKeyword( "PCI_REVISION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber) + Overrides.PciRevision = self.__Token + + if self.__IsKeyword( "COMPRESS"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber) + + if self.__Token.upper() == 'TRUE': + Overrides.NeedCompress = True + + if not self.__IsToken( "}"): + + if self.__Token not in ("PCI_CLASS_CODE", "PCI_VENDOR_ID", "PCI_DEVICE_ID", "PCI_REVISION", "COMPRESS"): + raise Warning("unknown attribute %s" % self.__Token, self.FileName, self.CurrentLineNumber) + + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + Obj.OverrideAttribs = Overrides + + ## __GetOptRomFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def __GetOptRomFileStatement(self, Obj): + + if not self.__IsKeyword( "FILE"): + return False + + FfsFileObj = OptRomFileStatement.OptRomFileStatement() + + if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"): + raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileType = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected File path", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileName = self.__Token + + if FfsFileObj.FileType == 'EFI': + self.__GetOptRomOverrides(FfsFileObj) + + Obj.FfsList.append(FfsFileObj) + + return True + + + ## __GetFvInFd() method + # + # Get FV list contained in FD + # + # @param self The object pointer + # @param FdName FD name + # @retval FvList list of FV in FD + # + def __GetFvInFd (self, FdName): + + FvList = [] + if FdName.upper() in self.Profile.FdDict.keys(): + FdObj = self.Profile.FdDict[FdName.upper()] + for elementRegion in FdObj.RegionList: + if elementRegion.RegionType == 'FV': + for elementRegionData in elementRegion.RegionDataList: + if elementRegionData != None and elementRegionData.upper() not in FvList: + FvList.append(elementRegionData.upper()) + return FvList + + ## __GetReferencedFdFvTuple() method + # + # Get FD and FV list referenced by a FFS file + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param RefFdList referenced FD by section + # @param RefFvList referenced FV by section + # + def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []): + + for FfsObj in FvObj.FfsList: + if isinstance(FfsObj, FfsFileStatement.FileStatement): + if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList: + RefFvList.append(FfsObj.FvName.upper()) + elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList: + RefFdList.append(FfsObj.FdName.upper()) + else: + self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) + + ## __GetReferencedFdFvTupleFromSection() method + # + # Get FD and FV list referenced by a FFS section + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param FdList referenced FD by section + # @param FvList referenced FV by section + # + def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []): + + SectionStack = [] + SectionStack.extend(FfsFile.SectionList) + while SectionStack != []: + SectionObj = SectionStack.pop() + if isinstance(SectionObj, FvImageSection.FvImageSection): + if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList: + FvList.append(SectionObj.FvName.upper()) + if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList: + FvList.append(SectionObj.Fv.UiFvName.upper()) + self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList) + + if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection): + SectionStack.extend(SectionObj.SectionList) + + ## CycleReferenceCheck() method + # + # Check whether cycle reference exists in FDF + # + # @param self The object pointer + # @retval True cycle reference exists + # @retval False Not exists cycle reference + # + def CycleReferenceCheck(self): + + CycleRefExists = False + + try: + for FvName in self.Profile.FvDict.keys(): + LogStr = "Cycle Reference Checking for FV: %s\n" % FvName + RefFvStack = [] + RefFvStack.append(FvName) + FdAnalyzedList = [] + + while RefFvStack != []: + FvNameFromStack = RefFvStack.pop() + if FvNameFromStack.upper() in self.Profile.FvDict.keys(): + FvObj = self.Profile.FvDict[FvNameFromStack.upper()] + else: + continue + + RefFdList = [] + RefFvList = [] + self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) + + for RefFdName in RefFdList: + if RefFdName in FdAnalyzedList: + continue + + LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack) + FvInFdList = self.__GetFvInFd(RefFdName) + if FvInFdList != []: + LogStr += "FD %s contains FV: " % RefFdName + for FvObj in FvInFdList: + LogStr += FvObj + LogStr += ' \n' + if FvObj not in RefFvStack: + RefFvStack.append(FvObj) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + FdAnalyzedList.append(RefFdName) + + for RefFvName in RefFvList: + LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack) + if RefFvName not in RefFvStack: + RefFvStack.append(RefFvName) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + + except Warning: + print LogStr + + finally: + return CycleRefExists + +if __name__ == "__main__": + parser = FdfParser("..\LakeportX64Pkg.fdf") + try: + parser.ParseFile() + parser.CycleReferenceCheck() + except Warning, X: + print str(X) + else: + print "Success!" + diff --git a/BaseTools/Source/Python/GenFds/Ffs.py b/BaseTools/Source/Python/GenFds/Ffs.py new file mode 100644 index 0000000000..aaa791763b --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Ffs.py @@ -0,0 +1,81 @@ +## @file +# process FFS generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from CommonDataClass.FdfClass import FDClassObject + +## generate FFS +# +# +class Ffs(FDClassObject): + + # mapping between MODULE type in FDF (from INF) and file type for GenFfs + ModuleTypeToFileType = { + 'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE', + 'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE', + 'PEIM' : 'EFI_FV_FILETYPE_PEIM', + 'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE', + 'DXE_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_SAL_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_SMM_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_RUNTIME_DRIVER': 'EFI_FV_FILETYPE_DRIVER', + 'UEFI_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'UEFI_APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION', + 'SMM_DRIVER' : 'EFI_FV_FILETYPE_SMM', + 'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE' + } + + # mapping between FILE type in FDF and file type for GenFfs + FdfFvFileTypeToFileType = { + 'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE', + 'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE', + 'PEIM' : 'EFI_FV_FILETYPE_PEIM', + 'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE', + 'FREEFORM' : 'EFI_FV_FILETYPE_FREEFORM', + 'DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION', + 'FV_IMAGE' : 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE', + 'RAW' : 'EFI_FV_FILETYPE_RAW', + 'PEI_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER', + 'SMM_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_SMM_DXE', + 'SMM' : 'EFI_FV_FILETYPE_SMM', + 'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE' + } + + # mapping between section type in FDF and file suffix + SectionSuffix = { + 'PE32' : '.pe32', + 'PIC' : '.pic', + 'TE' : '.te', + 'DXE_DEPEX' : '.dpx', + 'VERSION' : '.ver', + 'UI' : '.ui', + 'COMPAT16' : '.com16', + 'RAW' : '.raw', + 'FREEFORM_SUBTYPE_GUID': '.guid', + 'FV_IMAGE' : 'fv.sec', + 'COMPRESS' : '.com', + 'GUIDED' : '.guided', + 'PEI_DEPEX' : '.dpx', + 'SMM_DEPEX' : '.smm' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py new file mode 100644 index 0000000000..ed778f3d44 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py @@ -0,0 +1,118 @@ +## @file +# process FFS generation from FILE statement +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Ffs +import Rule +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +import StringIO +import subprocess +from CommonDataClass.FdfClass import FileStatementClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import GuidStructureByteArrayToGuidString + +## generate FFS from FILE +# +# +class FileStatement (FileStatementClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FileStatementClassObject.__init__(self) + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + + if self.NameGuid != None and self.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (self.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (self.NameGuid)) + self.NameGuid = RegistryGuidStr + + OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid) + if not os.path.exists(OutputDir): + os.makedirs(OutputDir) + + Dict.update(self.DefineVarDict) + SectionAlignments = None + if self.FvName != None : + Buffer = StringIO.StringIO('') + if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName)) + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) + FileName = Fv.AddToBuffer(Buffer) + SectionFiles = [FileName] + + elif self.FdName != None: + if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName)) + Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper()) + FvBin = {} + FileName = Fd.GenFd(FvBin) + SectionFiles = [FileName] + + elif self.FileName != None: + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)] + + else: + SectionFiles = [] + Index = 0 + SectionAlignments = [] + for section in self.SectionList : + Index = Index + 1 + SecIndex = '%d' %Index + sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict) + if sectList != []: + for sect in sectList: + SectionFiles.append(sect) + SectionAlignments.append(align) + + # + # Prepare the parameter + # + FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles, + Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType), + self.NameGuid, + Fixed=self.Fixed, + CheckSum=self.CheckSum, + Align=self.Alignment, + SectionAlign=SectionAlignments + ) + + return FfsFileOutput + + + diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py new file mode 100644 index 0000000000..0dcd96da2e --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -0,0 +1,582 @@ +## @file +# process FFS generation from INF statement +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Rule +import os +import shutil +from GenFdsGlobalVariable import GenFdsGlobalVariable +import Ffs +import subprocess +import sys +import Section +import RuleSimpleFile +import RuleComplexFile +from CommonDataClass.FdfClass import FfsInfStatementClassObject +from Common.String import * +from Common.Misc import PathClass +from Common.Misc import GuidStructureByteArrayToGuidString +from Common import EdkLogger +from Common.BuildToolError import * + +## generate FFS from INF +# +# +class FfsInfStatement(FfsInfStatementClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatementClassObject.__init__(self) + self.TargetOverrideList = [] + self.ShadowFromInfFile = None + self.KeepRelocFromRule = None + self.InDsc = True + self.OptRomDefs = {} + + ## __InfParse() method + # + # Parse inf file to get module information + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # + def __InfParse__(self, Dict = {}): + + GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) + + self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') + if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : + self.InfFileName = self.InfFileName[1:] + + if self.InfFileName.find('$') == -1: + InfPath = NormPath(self.InfFileName) + if not os.path.exists(InfPath): + InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) + if not os.path.exists(InfPath): + EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) + + self.CurrentArch = self.GetCurrentArch() + # + # Get the InfClass object + # + + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + if self.CurrentArch != None: + + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch] + # + # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath + # + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + if Inf.AutoGenVersion < 0x00010005: + self.ModuleType = Inf.ComponentType + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.KeepReloc == None and Inf.Shadow: + self.ShadowFromInfFile = Inf.Shadow + + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON'] + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.BinFileList == []: + EdkLogger.error("GenFds", GENFDS_ERROR, + "INF %s specified in FDF could not be found in build ARCH %s!" \ + % (self.InfFileName, GenFdsGlobalVariable.ArchList)) + + if len(self.SourceFileList) != 0 and not self.InDsc: + EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName)) + + if Inf._Defs != None and len(Inf._Defs) > 0: + self.OptRomDefs.update(Inf._Defs) + + GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName) + GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid) + GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType) + GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString) + GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName) + + # + # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ + # + + self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ + self.ModuleGuid + self.BaseName) + if not os.path.exists(self.OutputPath) : + os.makedirs(self.OutputPath) + + self.EfiOutputPath = self.__GetEFIOutPutPath__() + GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + # + # Parse Inf file get Module related information + # + + self.__InfParse__(Dict) + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType] + # + # For the rule only has simpleFile + # + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : + SectionOutputList = self.__GenSimpleFileSection__(Rule) + FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList) + return FfsOutput + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule) + FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments) + + return FfsOutput + + ## __ExtendMacro__() method + # + # Replace macro with its value + # + # @param self The object pointer + # @param String The string to be replaced + # @retval string Macro replaced string + # + def __ExtendMacro__ (self, String): + MacroDict = { + '$(INF_OUTPUT)' : self.EfiOutputPath, + '$(MODULE_NAME)' : self.BaseName, + '$(BUILD_NUMBER)': self.BuildNum, + '$(INF_VERSION)' : self.VersionString, + '$(NAMED_GUID)' : self.ModuleGuid + } + String = GenFdsGlobalVariable.MacroExtend(String, MacroDict) + return String + + ## __GetRule__() method + # + # Get correct rule for generating FFS for this INF + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRule__ (self) : + CurrentArchList = [] + if self.CurrentArch == None: + CurrentArchList = ['common'] + else: + CurrentArchList.append(self.CurrentArch) + + for CurrentArch in CurrentArchList: + RuleName = 'RULE' + \ + '.' + \ + CurrentArch.upper() + \ + '.' + \ + self.ModuleType.upper() + if self.Rule != None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule != None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + RuleName = 'RULE' + \ + '.' + \ + 'COMMON' + \ + '.' + \ + self.ModuleType.upper() + + if self.Rule != None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName)) + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule != None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + if Rule == None : + EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \ + % (RuleName, self.InfFileName)) + + ## __GetPlatformArchList__() method + # + # Get Arch list this INF built under + # + # @param self The object pointer + # @retval list Arch list + # + def __GetPlatformArchList__(self): + + InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)) + DscArchList = [] + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32'] + if PlatformDataBase != None: + if InfFileKey in PlatformDataBase.Modules: + DscArchList.append ('IA32') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64'] + if PlatformDataBase != None: + if InfFileKey in PlatformDataBase.Modules: + DscArchList.append ('X64') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('IPF') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('ARM') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('EBC') + + return DscArchList + + ## GetCurrentArch() method + # + # Get Arch list of the module from this INF is to be placed into flash + # + # @param self The object pointer + # @retval list Arch list + # + def GetCurrentArch(self) : + + TargetArchList = GenFdsGlobalVariable.ArchList + + PlatformArchList = self.__GetPlatformArchList__() + + CurArchList = TargetArchList + if PlatformArchList != []: + CurArchList = list(set (TargetArchList) & set (PlatformArchList)) + GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList)) + + ArchList = [] + if self.KeyStringList != []: + for Key in self.KeyStringList: + Key = GenFdsGlobalVariable.MacroExtend(Key) + Target, Tag, Arch = Key.split('_') + if Arch in CurArchList: + ArchList.append(Arch) + if Target not in self.TargetOverrideList: + self.TargetOverrideList.append(Target) + else: + ArchList = CurArchList + + UseArchList = TargetArchList + if self.UseArch != None: + UseArchList = [] + UseArchList.append(self.UseArch) + ArchList = list(set (UseArchList) & set (ArchList)) + + self.InfFileName = NormPath(self.InfFileName) + if len(PlatformArchList) == 0: + self.InDsc = False + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + if len(ArchList) == 1: + Arch = ArchList[0] + return Arch + elif len(ArchList) > 1: + if len(PlatformArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \ + % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList)))) + + ## __GetEFIOutPutPath__() method + # + # Get the output path for generated files + # + # @param self The object pointer + # @retval string Path that output files from this INF go to + # + def __GetEFIOutPutPath__(self): + Arch = '' + OutputPath = '' + (ModulePath, FileName) = os.path.split(self.InfFileName) + Index = FileName.find('.') + FileName = FileName[0:Index] + Arch = "NoneArch" + if self.CurrentArch != None: + Arch = self.CurrentArch + + OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], + Arch , + ModulePath, + FileName, + 'OUTPUT' + ) + OutputPath = os.path.realpath(OutputPath) + return OutputPath + + ## __GenSimpleFileSection__() method + # + # Generate section by specified file name or a list of files with file extension + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenSimpleFileSection__(self, Rule): + # + # Prepare the parameter of GenSection + # + FileList = [] + OutputFileList = [] + if Rule.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + Index = 1 + SectionType = Rule.SectionType + NoStrip = True + if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): + if self.KeepReloc != None: + NoStrip = self.KeepReloc + elif Rule.KeepReloc != None: + NoStrip = Rule.KeepReloc + elif self.ShadowFromInfFile != None: + NoStrip = self.ShadowFromInfFile + + if FileList != [] : + for File in FileList: + + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum + Index = Index + 1 + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(File, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Strip=True + ) + File = StrippedFile + + if SectionType == 'TE': + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Type='te' + ) + File = TeFile + + GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType]) + OutputFileList.append(OutputFile) + else: + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(GenSecInputFile, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)], + Strip=True + ) + GenSecInputFile = StrippedFile + + if SectionType == 'TE': + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Type='te' + ) + GenSecInputFile = TeFile + + GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType]) + OutputFileList.append(OutputFile) + + return OutputFileList + + ## __GenSimpleFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenSimpleFileFfs__(self, Rule, InputFileList): + FfsOutput = self.OutputPath + \ + os.sep + \ + self.__ExtendMacro__(Rule.NameGuid) + \ + '.ffs' + + GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid)) + InputSection = [] + SectionAlignments = [] + for InputFile in InputFileList: + InputSection.append(InputFile) + SectionAlignments.append(Rule.Alignment) + + if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=SectionAlignments + ) + return FfsOutput + + ## __GenComplexFileSection__() method + # + # Generate section by sections in Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule): + if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): + if Rule.KeepReloc != None: + self.KeepRelocFromRule = Rule.KeepReloc + SectFiles = [] + SectAlignments = [] + Index = 1 + for Sect in Rule.SectionList: + SecIndex = '%d' %Index + SectList = [] + if Rule.KeyStringList != []: + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self) + else : + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self) + for SecName in SectList : + SectFiles.append(SecName) + SectAlignments.append(Align) + Index = Index + 1 + return SectFiles, SectAlignments + + ## __GenComplexFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenComplexFileFfs__(self, Rule, InputFile, Alignments): + + if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile, + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=Alignments + ) + return FfsOutput + + ## __GetGenFfsCmdParameter__() method + # + # Create parameter string for GenFfs + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval tuple (FileType, Fixed, CheckSum, Alignment) + # + def __GetGenFfsCmdParameter__(self, Rule): + result = tuple() + result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType]) + if Rule.Fixed != False: + result += ('-x',) + if Rule.CheckSum != False: + result += ('-s',) + + if Rule.Alignment != None and Rule.Alignment != '': + result += ('-a', Rule.Alignment) + + return result diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py new file mode 100644 index 0000000000..74248f71c3 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Fv.py @@ -0,0 +1,215 @@ +## @file +# process FV generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 os +import shutil +import subprocess +import StringIO + +import Ffs +import AprioriSection +from GenFdsGlobalVariable import GenFdsGlobalVariable +from GenFds import GenFds +from CommonDataClass.FdfClass import FvClassObject +from Common.Misc import SaveFileOnChange + +T_CHAR_LF = '\n' + +## generate FV +# +# +class FV (FvClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FvClassObject.__init__(self) + self.FvInfFile = None + self.FvAddressFile = None + self.BaseAddress = None + self.InfFileName = None + self.FvAddressFileName = None + + ## AddToBuffer() + # + # Generate Fv and add it to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated FV data will be put + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) : + + if self.UiFvName.upper() in GenFds.FvBinDict.keys(): + return GenFds.FvBinDict[self.UiFvName.upper()] + + GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV ..." %self.UiFvName) + + self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict) + # + # First Process the Apriori section + # + MacroDict.update(self.DefineVarDict) + + GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !') + FfsFileList = [] + for AprSection in self.AprioriSectionList: + FileName = AprSection.GenFfs (self.UiFvName, MacroDict) + FfsFileList.append(FileName) + # Add Apriori file name to Inf file + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + + # Process Modules in FfsList + for FfsFile in self.FfsList : + FileName = FfsFile.GenFfs(MacroDict) + FfsFileList.append(FileName) + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + + SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False) + self.FvInfFile.close() + # + # Call GenFv tool + # + FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName) + FvOutputFile = FvOutputFile + '.Fv' + # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement) + if self.CreateFileName != None: + FvOutputFile = self.CreateFileName + + FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf') + shutil.copy(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName) + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList + ) + + # + # Write the Fv contents to Buffer + # + FvFileObj = open ( FvOutputFile,'r+b') + + GenFdsGlobalVariable.InfLogger( "\nGenerate %s FV Successfully" %self.UiFvName) + GenFdsGlobalVariable.SharpCounter = 0 + + Buffer.write(FvFileObj.read()) + FvFileObj.close() + GenFds.FvBinDict[self.UiFvName.upper()] = FvOutputFile + return FvOutputFile + + ## __InitializeInf__() + # + # Initilize the inf file to create FV + # + # @param self The object pointer + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # + def __InitializeInf__ (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1', VtfDict=None) : + # + # Create FV inf file + # + self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiFvName + '.inf') + self.FvInfFile = StringIO.StringIO() + + # + # Add [Options] + # + self.FvInfFile.writelines("[options]" + T_CHAR_LF) + if BaseAddress != None : + self.FvInfFile.writelines("EFI_BASE_ADDRESS = " + \ + BaseAddress + \ + T_CHAR_LF) + + if BlockSize != None: + self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize + \ + T_CHAR_LF) + if BlockNum != None: + self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockNum + \ + T_CHAR_LF) + else: + for BlockSize in self.BlockSizeList : + if BlockSize[0] != None: + self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize[0] + \ + T_CHAR_LF) + + if BlockSize[1] != None: + self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockSize[1] + \ + T_CHAR_LF) + + if self.BsBaseAddress != None: + self.FvInfFile.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.BsBaseAddress) + if self.RtBaseAddress != None: + self.FvInfFile.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.RtBaseAddress) + # + # Add attribute + # + self.FvInfFile.writelines("[attributes]" + T_CHAR_LF) + + self.FvInfFile.writelines("EFI_ERASE_POLARITY = " + \ + ' %s' %ErasePloarity + \ + T_CHAR_LF) + if not (self.FvAttributeDict == None): + for FvAttribute in self.FvAttributeDict.keys() : + self.FvInfFile.writelines("EFI_" + \ + FvAttribute + \ + ' = ' + \ + self.FvAttributeDict[FvAttribute] + \ + T_CHAR_LF ) + if self.FvAlignment != None: + self.FvInfFile.writelines("EFI_FVB2_ALIGNMENT_" + \ + self.FvAlignment.strip() + \ + " = TRUE" + \ + T_CHAR_LF) + + if self.FvNameGuid != None: + self.FvInfFile.writelines("EFI_FVNAME_GUID" + \ + " = %s" % self.FvNameGuid + \ + T_CHAR_LF) + # + # Add [Files] + # + + self.FvInfFile.writelines("[files]" + T_CHAR_LF) + if VtfDict != None and self.UiFvName in VtfDict.keys(): + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + VtfDict.get(self.UiFvName) + \ + T_CHAR_LF) + + diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py new file mode 100644 index 0000000000..3a3e714228 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FvImageSection.py @@ -0,0 +1,90 @@ +## @file +# process FV image section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 StringIO +from Ffs import Ffs +import subprocess +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +from CommonDataClass.FdfClass import FvImageSectionClassObject +from Common import EdkLogger +from Common.BuildToolError import * + +## generate FV image section +# +# +class FvImageSection(FvImageSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FvImageSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate FV image 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 = {}): + + OutputFileList = [] + if self.FvFileType != None: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension) + if IsSect : + return FileList, self.Alignment + + Num = SecNum + + for FileName in FileList: + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + # + # Generate Fv + # + if self.FvName != None: + Buffer = StringIO.StringIO('') + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) + if Fv != None: + self.Fv = Fv + FvFileName = self.Fv.AddToBuffer(Buffer, MacroDict = Dict) + else: + if self.FvFileName != None: + FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName) + + # + # Prepare the parameter of GenSection + # + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + OutputFileList.append(OutputFile) + + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py new file mode 100644 index 0000000000..2bc416f828 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -0,0 +1,486 @@ +## @file +# generate flash image +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from optparse import OptionParser +import sys +import os +import linecache +import FdfParser +from Common.BuildToolError import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +from Workspace.WorkspaceDatabase import WorkspaceDatabase +from Workspace.BuildClassObject import PcdClassObject +from Workspace.BuildClassObject import ModuleBuildClassObject +import RuleComplexFile +from EfiSection import EfiSection +import StringIO +import Common.TargetTxtClassObject as TargetTxtClassObject +import Common.ToolDefClassObject as ToolDefClassObject +import Common.DataType +import Common.GlobalData as GlobalData +from Common import EdkLogger +from Common.String import * +from Common.Misc import DirCache,PathClass + +## Version and Copyright +versionNumber = "1.0" +__version__ = "%prog Version " + versionNumber +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." + +## Tool entrance method +# +# This method mainly dispatch specific methods per the command line options. +# If no error found, return zero value so the caller of this tool can know +# if it's executed successfully or not. +# +# @retval 0 Tool was successful +# @retval 1 Tool failed +# +def main(): + global Options + Options = myOptionParser() + + global Workspace + Workspace = "" + ArchList = None + ReturnCode = 0 + + EdkLogger.Initialize() + try: + if Options.verbose != None: + EdkLogger.SetLevel(EdkLogger.VERBOSE) + GenFdsGlobalVariable.VerboseMode = True + + if Options.FixedAddress != None: + GenFdsGlobalVariable.FixedLoadAddress = True + + if Options.quiet != None: + EdkLogger.SetLevel(EdkLogger.QUIET) + if Options.debug != None: + EdkLogger.SetLevel(Options.debug + 1) + GenFdsGlobalVariable.DebugLevel = Options.debug + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + if (Options.Workspace == None): + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + elif not os.path.exists(Options.Workspace): + EdkLogger.error("GenFds", BuildToolError.PARAMETER_INVALID, "WORKSPACE is invalid", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + else: + Workspace = os.path.normcase(Options.Workspace) + GenFdsGlobalVariable.WorkSpaceDir = Workspace + if 'EDK_SOURCE' in os.environ.keys(): + GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE']) + if (Options.debug): + GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace) + os.chdir(GenFdsGlobalVariable.WorkSpaceDir) + + if (Options.filename): + FdfFilename = Options.filename + FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename") + + if (Options.BuildTarget): + GenFdsGlobalVariable.TargetName = Options.BuildTarget + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target") + + if (Options.ToolChain): + GenFdsGlobalVariable.ToolChainTag = Options.ToolChain + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag") + + if FdfFilename[0:2] == '..': + FdfFilename = os.path.realpath(FdfFilename) + if FdfFilename[1] != ':': + FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) + + if not os.path.exists(FdfFilename): + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename) + GenFdsGlobalVariable.FdfFile = FdfFilename + GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename) + + if (Options.activePlatform): + ActivePlatform = Options.activePlatform + ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) + + if ActivePlatform[0:2] == '..': + ActivePlatform = os.path.realpath(ActivePlatform) + + if ActivePlatform[1] != ':': + ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) + + if not os.path.exists(ActivePlatform) : + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!") + + if ActivePlatform.find(Workspace) == -1: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!") + + ActivePlatform = ActivePlatform.replace(Workspace, '') + if len(ActivePlatform) > 0 : + if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/': + ActivePlatform = ActivePlatform[1:] + else: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!") + else : + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform") + + GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace) + + BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt")) + if os.path.isfile(BuildConfigurationFile) == True: + TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile) + else: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) + + if Options.Macros: + for Pair in Options.Macros: + Pair.strip('"') + List = Pair.split('=') + if len(List) == 2: + FdfParser.InputMacroDict[List[0].strip()] = List[1].strip() + if List[0].strip() == "EFI_SOURCE": + GlobalData.gEfiSource = List[1].strip() + elif List[0].strip() == "EDK_SOURCE": + GlobalData.gEdkSource = List[1].strip() + else: + GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip() + else: + FdfParser.InputMacroDict[List[0].strip()] = None + + """call Workspace build create database""" + os.environ["WORKSPACE"] = Workspace + BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines) + BuildWorkSpace.InitDatabase() + + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles = DirCache(Workspace) + GlobalData.gWorkspace = Workspace + + if (Options.archList) : + ArchList = Options.archList.split(',') + else: +# EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH") + ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList + + TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList) + if len(TargetArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList))) + + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].OutputDirectory) + + if (Options.outputDir): + OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir) + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine + else: + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) + + for Key in GenFdsGlobalVariable.OutputDirDict: + OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] + if OutputDir[0:2] == '..': + OutputDir = os.path.realpath(OutputDir) + + if OutputDir[1] != ':': + OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) + + if not os.path.exists(OutputDir): + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir) + GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir + + """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ + FdfParserObj = FdfParser.FdfParser(FdfFilename) + FdfParserObj.ParseFile() + + if FdfParserObj.CycleReferenceCheck(): + EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") + + if (Options.uiFdName) : + if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys(): + GenFds.OnlyGenerateThisFd = Options.uiFdName + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID, + "No such an FD in FDF file: %s" % Options.uiFdName) + + if (Options.uiFvName) : + if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys(): + GenFds.OnlyGenerateThisFv = Options.uiFvName + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID, + "No such an FV in FDF file: %s" % Options.uiFvName) + + """Modify images from build output if the feature of loading driver at fixed address is on.""" + if GenFdsGlobalVariable.FixedLoadAddress: + GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) + """Call GenFds""" + GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) + + """Display FV space info.""" + GenFds.DisplayFvSpaceInfo(FdfParserObj) + + except FdfParser.Warning, X: + EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False) + ReturnCode = BuildToolError.FORMAT_INVALID + except FatalError, X: + if Options.debug != None: + import traceback + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = X.args[0] + except: + import traceback + EdkLogger.error( + "\nPython", + CODE_ERROR, + "Tools code failure", + ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n", + RaiseError=False + ) + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = CODE_ERROR + return ReturnCode + +gParamCheck = [] +def SingleCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + setattr(parser.values, option.dest, value) + gParamCheck.append(option) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +## Parse command line options +# +# Using standard Python module optparse to parse command line option of this tool. +# +# @retval Opt A optparse.Values object containing the parsed options +# @retval Args Target of build command +# +def myOptionParser(): + usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\"" + Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber)) + Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback) + Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM or EBC which should be built, overrides target.txt?s TARGET_ARCH") + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.") + Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName") + Parser.add_option("-b", "--buildtarget", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".") + Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.") + (Options, args) = Parser.parse_args() + return Options + +## The class implementing the EDK2 flash image generation process +# +# This process includes: +# 1. Collect workspace information, includes platform and module information +# 2. Call methods of Fd class to generate FD +# 3. Call methods of Fv class to generate FV that not belong to FD +# +class GenFds : + FdfParsef = None + # FvName in FDF, FvBinFile name + FvBinDict = {} + OnlyGenerateThisFd = None + OnlyGenerateThisFv = None + + ## GenFd() + # + # @param OutputDir Output directory + # @param FdfParser FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + def GenFd (OutputDir, FdfParser, WorkSpace, ArchList): + GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList) + + GenFdsGlobalVariable.VerboseLogger(" Gen Fd !") + if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper()) + if FdObj != None: + FdObj.GenFd(GenFds.FvBinDict) + elif GenFds.OnlyGenerateThisFv == None: + for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName] + FdObj.GenFd(GenFds.FvBinDict) + + GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ") + if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper()) + if FvObj != None: + Buffer = StringIO.StringIO() + # Get FV base Address + FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj)) + Buffer.close() + return + elif GenFds.OnlyGenerateThisFd == None: + for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + Buffer = StringIO.StringIO('') + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName] + # Get FV base Address + FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj)) + Buffer.close() + + if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None: + GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !") + for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList: + CapsuleObj.GenCapsule() + + if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}: + GenFdsGlobalVariable.VerboseLogger(" Gen Option ROM !") + for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys(): + OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName] + OptRomObj.AddToBuffer(None) + + ## GetFvBlockSize() + # + # @param FvObj Whose block size to get + # @retval int Block size value + # + def GetFvBlockSize(FvObj): + DefaultBlockSize = 0x10000 + FdObj = None + if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()] + if FdObj == None: + for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + for ElementRegion in ElementFd.RegionList: + if ElementRegion.RegionType == 'FV': + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + return DefaultBlockSize + else: + for ElementRegion in FdObj.RegionList: + if ElementRegion.RegionType == 'FV': + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + return DefaultBlockSize + + ## DisplayFvSpaceInfo() + # + # @param FvObj Whose block size to get + # @retval None + # + def DisplayFvSpaceInfo(FdfParser): + + FvSpaceInfoList = [] + MaxFvNameLength = 0 + for FvName in FdfParser.Profile.FvDict: + if len(FvName) > MaxFvNameLength: + MaxFvNameLength = len(FvName) + FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map') + if os.path.exists(FvSpaceInfoFileName): + FileLinesList = linecache.getlines(FvSpaceInfoFileName) + TotalFound = False + Total = '' + UsedFound = False + Used = '' + FreeFound = False + Free = '' + for Line in FileLinesList: + NameValue = Line.split('=') + if len(NameValue) == 2: + if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE': + TotalFound = True + Total = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE': + UsedFound = True + Used = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE': + FreeFound = True + Free = NameValue[1].strip() + + if TotalFound and UsedFound and FreeFound: + FvSpaceInfoList.append((FvName, Total, Used, Free)) + + GenFdsGlobalVariable.InfLogger('\nFV Space Information') + for FvSpaceInfo in FvSpaceInfoList: + Name = FvSpaceInfo[0] + TotalSizeValue = long(FvSpaceInfo[1], 0) + UsedSizeValue = long(FvSpaceInfo[2], 0) + FreeSizeValue = long(FvSpaceInfo[3], 0) + GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + str((UsedSizeValue+0.0)/TotalSizeValue)[0:4].lstrip('0.') + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free') + + ## PreprocessImage() + # + # @param BuildDb Database from build meta data files + # @param DscFile modules from dsc file will be preprocessed + # @retval None + # + def PreprocessImage(BuildDb, DscFile): + PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds + PcdValue = '' + for Key in PcdDict: + PcdObj = PcdDict[Key] + if PcdObj.TokenCName == 'PcdBsBaseAddress': + PcdValue = PcdObj.DefaultValue + break + + if PcdValue == '': + return + + Int64PcdValue = long(PcdValue, 0) + if Int64PcdValue == 0 or Int64PcdValue < -1: + return + + TopAddress = 0 + if Int64PcdValue > 0: + TopAddress = Int64PcdValue + + ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules + for Key in ModuleDict: + ModuleObj = BuildDb.BuildObject[Key, 'COMMON'] + print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType + + ##Define GenFd as static function + GenFd = staticmethod(GenFd) + GetFvBlockSize = staticmethod(GetFvBlockSize) + DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo) + PreprocessImage = staticmethod(PreprocessImage) + +if __name__ == '__main__': + r = main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: r = 1 + sys.exit(r) + diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py new file mode 100644 index 0000000000..d556ce7ade --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -0,0 +1,472 @@ +## @file +# Global variables for GenFds +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 os +import sys +import subprocess +import struct +import array + +from Common.BuildToolError import * +from Common import EdkLogger +from Common.Misc import SaveFileOnChange + +## Global variables +# +# +class GenFdsGlobalVariable: + FvDir = '' + OutputDirDict = {} + BinDir = '' + # will be FvDir + os.sep + 'Ffs' + FfsDir = '' + FdfParser = None + LibDir = '' + WorkSpace = None + WorkSpaceDir = '' + EdkSourceDir = '' + OutputDirFromDscDict = {} + TargetName = '' + ToolChainTag = '' + RuleDict = {} + ArchList = None + VtfDict = {} + ActivePlatform = None + FvAddressFileName = '' + VerboseMode = False + DebugLevel = -1 + SharpCounter = 0 + SharpNumberPerLine = 40 + FdfFile = '' + FdfFileTimeStamp = 0 + FixedLoadAddress = False + + SectionHeader = struct.Struct("3B 1B") + + ## SetDir() + # + # @param OutputDir Output directory + # @param FdfParser FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): + GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir) +# GenFdsGlobalVariable.OutputDirDict = OutputDir + GenFdsGlobalVariable.FdfParser = FdfParser + GenFdsGlobalVariable.WorkSpace = WorkSpace + GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV') + if not os.path.exists(GenFdsGlobalVariable.FvDir) : + os.makedirs(GenFdsGlobalVariable.FvDir) + GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') + if not os.path.exists(GenFdsGlobalVariable.FfsDir) : + os.makedirs(GenFdsGlobalVariable.FfsDir) + if ArchList != None: + GenFdsGlobalVariable.ArchList = ArchList + + T_CHAR_LF = '\n' + # + # Create FV Address inf file + # + GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') + FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w') + # + # Add [Options] + # + FvAddressFile.writelines("[options]" + T_CHAR_LF) + BsAddress = '0' + for Arch in ArchList: + if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress: + BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress + break + + FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ + BsAddress + \ + T_CHAR_LF) + + RtAddress = '0' + for Arch in ArchList: + if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress: + RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress + + FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ + RtAddress + \ + T_CHAR_LF) + + FvAddressFile.close() + + ## ReplaceWorkspaceMacro() + # + # @param String String that may contain macro + # + def ReplaceWorkspaceMacro(String): + Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + else: + Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String) + return os.path.normpath(Str) + + ## Check if the input files are newer than output files + # + # @param Output Path of output file + # @param Input Path list of input files + # + # @retval True if Output doesn't exist, or any Input is newer + # @retval False if all Input is older than Output + # + @staticmethod + def NeedsUpdate(Output, Input): + if not os.path.exists(Output): + return True + # always update "Output" if no "Input" given + if Input == None or len(Input) == 0: + return True + + # if fdf file is changed after the 'Output" is generated, update the 'Output' + OutputTime = os.path.getmtime(Output) + if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: + return True + + for F in Input: + # always update "Output" if any "Input" doesn't exist + if not os.path.exists(F): + return True + # always update "Output" if any "Input" is newer than "Output" + if os.path.getmtime(F) > OutputTime: + return True + return False + + @staticmethod + def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, + GuidHdrLen=None, GuidAttr=None, Ui=None, Ver=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenSec"] + if Type not in [None, '']: + Cmd += ["-s", Type] + if CompressionType not in [None, '']: + Cmd += ["-c", CompressionType] + if Guid != None: + Cmd += ["-g", Guid] + if GuidHdrLen not in [None, '']: + Cmd += ["-l", GuidHdrLen] + if GuidAttr not in [None, '']: + Cmd += ["-r", GuidAttr] + + if Ui not in [None, '']: + #Cmd += ["-n", '"' + Ui + '"'] + SectionData = array.array('B', [0,0,0,0]) + SectionData.fromstring(Ui.encode("utf_16_le")) + SectionData.append(0) + SectionData.append(0) + Len = len(SectionData) + GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) + SaveFileOnChange(Output, SectionData.tostring()) + elif Ver not in [None, '']: + #Cmd += ["-j", Ver] + SectionData = array.array('B', [0,0,0,0]) + SectionData.fromstring(Ver.encode("utf_16_le")) + SectionData.append(0) + SectionData.append(0) + Len = len(SectionData) + GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x14) + SaveFileOnChange(Output, SectionData.tostring()) + else: + Cmd += ["-o", Output] + Cmd += Input + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") + + @staticmethod + def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, + SectionAlign=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFfs", "-t", Type, "-g", Guid] + if Fixed == True: + Cmd += ["-x"] + if CheckSum: + Cmd += ["-s"] + if Align not in [None, '']: + Cmd += ["-a", Align] + + Cmd += ["-o", Output] + for I in range(0, len(Input)): + Cmd += ("-i", Input[I]) + if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']: + Cmd += ("-n", SectionAlign[I]) + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") + + @staticmethod + def GenerateFirmwareVolume(Output, Input, BaseAddress=None, Capsule=False, Dump=False, + AddressFile=None, MapFile=None, FfsList=[]): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFv"] + if BaseAddress not in [None, '']: + Cmd += ["-r", BaseAddress] + if Capsule: + Cmd += ["-c"] + if Dump: + Cmd += ["-p"] + if AddressFile not in [None, '']: + Cmd += ["-a", AddressFile] + if MapFile not in [None, '']: + Cmd += ["-m", MapFile] + Cmd += ["-o", Output] + for I in Input: + Cmd += ["-i", I] + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") + + @staticmethod + def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenVtf"] + if BaseAddress not in [None, ''] and FvSize not in [None, ''] \ + and len(BaseAddress) == len(FvSize): + for I in range(0, len(BaseAddress)): + Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]] + Cmd += ["-o", Output] + for F in Input: + Cmd += ["-f", F] + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF") + + @staticmethod + def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, + Strip=False, Replace=False, TimeStamp=None, Join=False, + Align=None, Padding=None, Convert=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFw"] + if Type.lower() == "te": + Cmd += ["-t"] + if SubType not in [None, '']: + Cmd += ["-e", SubType] + if TimeStamp not in [None, '']: + Cmd += ["-s", TimeStamp] + if Align not in [None, '']: + Cmd += ["-a", Align] + if Padding not in [None, '']: + Cmd += ["-p", Padding] + if Zero: + Cmd += ["-z"] + if Strip: + Cmd += ["-l"] + if Replace: + Cmd += ["-r"] + if Join: + Cmd += ["-j"] + if Convert: + Cmd += ["-m"] + Cmd += ["-o", Output] + Cmd += Input + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") + + @staticmethod + def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, + Revision=None, DeviceId=None, VendorId=None): +# if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): +# return +# GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["EfiRom"] + if len(EfiInput) > 0: + + if Compress: + Cmd += ["-ec"] + else: + Cmd += ["-e"] + + for EfiFile in EfiInput: + Cmd += [EfiFile] + + if len(BinaryInput) > 0: + Cmd += ["-b"] + for BinFile in BinaryInput: + Cmd += [BinFile] + + if ClassCode != None: + Cmd += ["-l", ClassCode] + if Revision != None: + Cmd += ["-r", Revision] + if DeviceId != None: + Cmd += ["-i", DeviceId] + if VendorId != None: + Cmd += ["-f", VendorId] + + Cmd += ["-o", Output] + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") + + @staticmethod + def GuidTool(Output, Input, ToolPath, Options=''): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = [ToolPath, Options] + Cmd += ["-o", Output] + Cmd += Input + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath) + + def CallExternalTool (cmd, errorMess): + + if type(cmd) not in (tuple, list): + GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") + + if GenFdsGlobalVariable.DebugLevel != -1: + cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) + GenFdsGlobalVariable.InfLogger (cmd) + + if GenFdsGlobalVariable.VerboseMode: + cmd += ('-v',) + GenFdsGlobalVariable.InfLogger (cmd) + else: + sys.stdout.write ('#') + sys.stdout.flush() + GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 + if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: + sys.stdout.write('\n') + + try: + PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE) + except Exception, X: + EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) + (out, error) = PopenObject.communicate() + + while PopenObject.returncode == None : + PopenObject.wait() + if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: + GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode) + GenFdsGlobalVariable.InfLogger (out) + GenFdsGlobalVariable.InfLogger (error) + if PopenObject.returncode != 0: + print "###", cmd + EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, errorMess) + + def VerboseLogger (msg): + EdkLogger.verbose(msg) + + def InfLogger (msg): + EdkLogger.info(msg) + + def ErrorLogger (msg, File = None, Line = None, ExtraData = None): + EdkLogger.error('GenFds', BuildToolError.GENFDS_ERROR, msg, File, Line, ExtraData) + + def DebugLogger (Level, msg): + EdkLogger.debug(Level, msg) + + ## ReplaceWorkspaceMacro() + # + # @param Str String that may contain macro + # @param MacroDict Dictionary that contains macro value pair + # + def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'): + if Str == None : + return None + + Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir, + '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir, +# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, + '$(TARGET)' : GenFdsGlobalVariable.TargetName, + '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag + } + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] + if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList: + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] + + Dict['$(OUTPUT_DIRECTORY)'] = OutputDir + + if MacroDict != None and len (MacroDict) != 0: + Dict.update(MacroDict) + + for key in Dict.keys(): + if Str.find(key) >= 0 : + Str = Str.replace (key, Dict[key]) + + if Str.find('$(ARCH)') >= 0: + if len(GenFdsGlobalVariable.ArchList) == 1: + Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) + + return Str + + ## GetPcdValue() + # + # @param PcdPattern pattern that labels a PCD. + # + def GetPcdValue (PcdPattern): + if PcdPattern == None : + return None + PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.') + TokenSpace = PcdPair[0] + TokenCName = PcdPair[1] + + PcdValue = '' + for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList: + PcdDict = Platform.Pcds + for Key in PcdDict: + PcdObj = PcdDict[Key] + if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): + if PcdObj.Type != 'FixedAtBuild': + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) + if PcdObj.DatumType != 'VOID*': + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) + + PcdValue = PcdObj.DefaultValue + return PcdValue + + for Package in GenFdsGlobalVariable.WorkSpace.PackageList: + PcdDict = Package.Pcds + for Key in PcdDict: + PcdObj = PcdDict[Key] + if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): + if PcdObj.Type != 'FixedAtBuild': + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) + if PcdObj.DatumType != 'VOID*': + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) + + PcdValue = PcdObj.DefaultValue + return PcdValue + + return PcdValue + + SetDir = staticmethod(SetDir) + ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro) + CallExternalTool = staticmethod(CallExternalTool) + VerboseLogger = staticmethod(VerboseLogger) + InfLogger = staticmethod(InfLogger) + ErrorLogger = staticmethod(ErrorLogger) + DebugLogger = staticmethod(DebugLogger) + MacroExtend = staticmethod (MacroExtend) + GetPcdValue = staticmethod(GetPcdValue) diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py new file mode 100644 index 0000000000..e111e0fe50 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GuidSection.py @@ -0,0 +1,190 @@ +## @file +# process GUIDed section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 * + +## 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() + Index = 0 + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' %(SecNum,Index) + ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList,FfsInf, Dict) + if ReturnSectList != []: + for file in ReturnSectList: + SectFile += (file,) + + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + Ffs.SectionSuffix['GUIDED'] + OutputFile = os.path.normpath(OutputFile) + + ExternalTool = None + if self.NameGuid != None: + ExternalTool = 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]) + 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: + # + # Call GenSection with DUMMY section type. + # + GenFdsGlobalVariable.GenerateSection(OutputFile+".dummy", SectFile) + # + # Use external tool process the Output + # + InputFile = OutputFile+".dummy" + TempFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + '.tmp' + TempFile = os.path.normpath(TempFile) + + ExternalToolCmd = ( + ExternalTool, + '-e', + '-o', TempFile, + InputFile, + ) + + # + # Call external tool + # + GenFdsGlobalVariable.GuidTool(TempFile, [InputFile], ExternalTool, '-e') + + # + # Call Gensection Add Secntion Header + # + Attribute = None + if self.ProcessRequired == True: + Attribute = 'PROCSSING_REQUIRED' + if self.AuthStatusValid == True: + Attribute = 'AUTH_STATUS_VALID' + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute) + OutputFileList = [] + OutputFileList.append(OutputFile) + 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') + 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 + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py new file mode 100644 index 0000000000..c360c6d9ad --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py @@ -0,0 +1,50 @@ +## @file +# process OptionROM generation from FILE statement +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 os + +from GenFdsGlobalVariable import GenFdsGlobalVariable +## +# +# +class OptRomFileStatement: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.FileName = None + self.FileType = None + self.OverrideAttribs = None + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + + if self.FileName != None: + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + + return self.FileName + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py new file mode 100644 index 0000000000..b9f0af54c9 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py @@ -0,0 +1,147 @@ +## @file +# process OptionROM generation from INF statement +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 RuleSimpleFile +import RuleComplexFile +import Section +import OptionRom +import Common.GlobalData as GlobalData + +from Common.DataType import * +from Common.String import * +from FfsInfStatement import FfsInfStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable + +## +# +# +class OptRomInfStatement (FfsInfStatement): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatement.__init__(self) + self.OverrideAttribs = None + + ## __GetOptRomParams() method + # + # Parse inf file to get option ROM related parameters + # + # @param self The object pointer + # + def __GetOptRomParams(self): + + if self.OverrideAttribs == None: + self.OverrideAttribs = OptionRom.OverrideAttribs() + + if self.OverrideAttribs.PciVendorId == None: + self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID') + + if self.OverrideAttribs.PciClassCode == None: + self.OverrideAttribs.PciClassCode = self.OptRomDefs.get ('PCI_CLASS_CODE') + + if self.OverrideAttribs.PciDeviceId == None: + self.OverrideAttribs.PciDeviceId = self.OptRomDefs.get ('PCI_DEVICE_ID') + + if self.OverrideAttribs.PciRevision == None: + self.OverrideAttribs.PciRevision = self.OptRomDefs.get ('PCI_REVISION') + +# InfObj = GenFdsGlobalVariable.WorkSpace.BuildObject[self.PathClassObj, self.CurrentArch] +# RecordList = InfObj._RawData[MODEL_META_DATA_HEADER, InfObj._Arch, InfObj._Platform] +# for Record in RecordList: +# Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) +# Name = Record[0] + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @retval string Generated .efi file name + # + def GenFfs(self): + # + # Parse Inf file get Module related information + # + + self.__InfParse__() + self.__GetOptRomParams() + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType] + # + # For the rule only has simpleFile + # + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : + EfiOutputList = self.__GenSimpleFileSection__(Rule) + return EfiOutputList + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + EfiOutputList = self.__GenComplexFileSection__(Rule) + return EfiOutputList + + ## __GenSimpleFileSection__() method + # + # Get .efi files according to simple rule. + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenSimpleFileSection__(self, Rule): + # + # Prepare the parameter of GenSection + # + + OutputFileList = [] + if Rule.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + OutputFileList.append(GenSecInputFile) + else: + OutputFileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + return OutputFileList + + + ## __GenComplexFileSection__() method + # + # Get .efi by sections in complex Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule): + + OutputFileList = [] + for Sect in Rule.SectionList: + if Sect.SectionType == 'PE32': + if Sect.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Sect.FileName) + OutputFileList.append(GenSecInputFile) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Sect.FileExtension) + OutputFileList.extend(FileList) + + return OutputFileList + + \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py new file mode 100644 index 0000000000..e102e65f1c --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptionRom.py @@ -0,0 +1,140 @@ +## @file +# process OptionROM generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 os +import shutil +import subprocess +import StringIO + +import OptRomInfStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable +from GenFds import GenFds +from CommonDataClass.FdfClass import OptionRomClassObject +from Common.Misc import SaveFileOnChange +from Common import EdkLogger +from Common.BuildToolError import * + +T_CHAR_LF = '\n' + +## +# +# +class OPTIONROM (OptionRomClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + OptionRomClassObject.__init__(self) + + + ## AddToBuffer() + # + # Generate Option ROM + # + # @param self The object pointer + # @param Buffer The buffer generated OptROM data will be put + # @retval string Generated OptROM file path + # + def AddToBuffer (self, Buffer) : + + GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName) + + EfiFileList = [] + BinFileList = [] + + # Process Modules in FfsList + for FfsFile in self.FfsList : + + if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement): + FilePathNameList = FfsFile.GenFfs() + if len(FilePathNameList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName)) + if FfsFile.OverrideAttribs == None: + EfiFileList.extend(FilePathNameList) + else: + FileName = os.path.basename(FilePathNameList[0]) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + FilePathNameList, + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId) + BinFileList.append(TmpOutputFile) + else: + FilePathName = FfsFile.GenFfs() + if FfsFile.OverrideAttribs != None: + FileName = os.path.basename(FilePathName) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + [FilePathName], + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId) + BinFileList.append(TmpOutputFile) + else: + if FfsFile.FileType == 'EFI': + EfiFileList.append(FilePathName) + else: + BinFileList.append(FilePathName) + + # + # Call EfiRom tool + # + OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + OutputFile = OutputFile + '.rom' + + GenFdsGlobalVariable.GenerateOptionRom( + OutputFile, + EfiFileList, + BinFileList + ) + + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName) + GenFdsGlobalVariable.SharpCounter = 0 + + return OutputFile + +class OverrideAttribs: + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + + self.PciVendorId = None + self.PciClassCode = None + self.PciDeviceId = None + self.PciRevision = None + self.NeedCompress = False + + \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py new file mode 100644 index 0000000000..ed16c6fa98 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Region.py @@ -0,0 +1,240 @@ +## @file +# process FD Region generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from struct import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +import StringIO +from CommonDataClass.FdfClass import RegionClassObject +import os +from Common import EdkLogger +from Common.BuildToolError import * + + +## generate Region +# +# +class Region(RegionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RegionClassObject.__init__(self) + + + ## AddToBuffer() + # + # Add region data to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated region data will be put + # @param BaseAddress base address of region + # @param BlockSize block size of region + # @param BlockNum How many blocks in region + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + + def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}): + Size = self.Size + GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset) + GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" %Size) + GenFdsGlobalVariable.SharpCounter = 0 + + if self.RegionType == 'FV': + # + # Get Fv from FvDict + # + FvBuffer = StringIO.StringIO('') + RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList) + RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize) + + self.FvAddress = int(BaseAddress, 16) + self.Offset + FvBaseAddress = '0x%X' %self.FvAddress + + for RegionData in self.RegionDataList: + + if RegionData.endswith(".fv"): + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s'%RegionData) + if RegionData[1] != ':' : + RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + BinFile = open (RegionData, 'r+b') + FvBuffer.write(BinFile.read()) + if FvBuffer.len > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV File (%s) is larger than Region Size 0x%X specified." \ + % (RegionData, Size)) + break + + if RegionData.upper() in FvBinDict.keys(): + continue + + FvObj = None + if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) + + if FvObj != None : + GenFdsGlobalVariable.InfLogger(' Region Name = FV') + # + # Call GenFv tool + # + BlockSize = RegionBlockSize + BlockNum = RegionBlockNum + if FvObj.BlockSizeList != []: + if FvObj.BlockSizeList[0][0] != None: + BlockSize = FvObj.BlockSizeList[0][0] + if FvObj.BlockSizeList[0][1] != None: + BlockNum = FvObj.BlockSizeList[0][1] + self.FvAddress = self.FvAddress + FvBuffer.len + FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment) + if self.FvAddress % FvAlignValue != 0: + EdkLogger.error("GenFds", GENFDS_ERROR, + "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment)) + FvBaseAddress = '0x%X' %self.FvAddress + FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict) + + if FvBuffer.len > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData)) + + + if FvBuffer.len > 0: + Buffer.write(FvBuffer.getvalue()) + else: + BinFile = open (FileName, 'rb') + Buffer.write(BinFile.read()) + + FvBuffer.close() + + if self.RegionType == 'FILE': + FvBuffer = StringIO.StringIO('') + for RegionData in self.RegionDataList: + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + GenFdsGlobalVariable.InfLogger(' Region File Name = FILE: %s'%RegionData) + if RegionData[1] != ':' : + RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + BinFile = open (RegionData, 'r+b') + FvBuffer.write(BinFile.read()) + if FvBuffer.len > Size : + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of File (%s) large than Region Size " % RegionData) + + # + # If File contents less than region size, append "0xff" after it + # + if FvBuffer.len < Size: + for index in range(0, (Size-FvBuffer.len)): + if (ErasePolarity == '1'): + FvBuffer.write(pack('B', int('0xFF', 16))) + else: + FvBuffer.write(pack('B', int('0x00', 16))) + Buffer.write(FvBuffer.getvalue()) + FvBuffer.close() + + if self.RegionType == 'DATA' : + GenFdsGlobalVariable.InfLogger(' Region Name = DATA') + DataSize = 0 + for RegionData in self.RegionDataList: + Data = RegionData.split(',') + DataSize = DataSize + len(Data) + if DataSize > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ") + else: + for item in Data : + Buffer.write(pack('B', int(item, 16))) + if DataSize < Size: + if (ErasePolarity == '1'): + PadData = 0xFF + else: + PadData = 0 + for i in range(Size - DataSize): + Buffer.write(pack('B', PadData)) + + if self.RegionType == None: + GenFdsGlobalVariable.InfLogger(' Region Name = None') + if (ErasePolarity == '1') : + PadData = 0xFF + else : + PadData = 0 + for i in range(0, Size): + Buffer.write(pack('B', PadData)) + + def GetFvAlignValue(self, Str): + AlignValue = 1 + Granu = 1 + Str = Str.strip().upper() + if Str.endswith('K'): + Granu = 1024 + Str = Str[:-1] + elif Str.endswith('M'): + Granu = 1024*1024 + Str = Str[:-1] + elif Str.endswith('G'): + Granu = 1024*1024*1024 + Str = Str[:-1] + else: + pass + + AlignValue = int(Str)*Granu + return AlignValue + ## BlockSizeOfRegion() + # + # @param BlockSizeList List of block information + # @retval int Block size of region + # + def BlockSizeOfRegion(self, BlockSizeList): + Offset = 0x00 + BlockSize = 0 + for item in BlockSizeList: + Offset = Offset + item[0] * item[1] + GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset) + GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset) + + if self.Offset < Offset : + if Offset - self.Offset < self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \ + % (self.Offset, item[0])) + BlockSize = item[0] + GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize) + return BlockSize + return BlockSize + + ## BlockNumOfRegion() + # + # @param BlockSize block size of region + # @retval int Block number of region + # + def BlockNumOfRegion (self, BlockSize): + if BlockSize == 0 : + EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset) + BlockNum = self.Size / BlockSize + GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum) + return BlockNum + diff --git a/BaseTools/Source/Python/GenFds/Rule.py b/BaseTools/Source/Python/GenFds/Rule.py new file mode 100644 index 0000000000..40a5f88bab --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Rule.py @@ -0,0 +1,29 @@ +## @file +# Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from CommonDataClass.FdfClass import RuleClassObject + +## Rule base class +# +# +class Rule(RuleClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleComplexFile.py b/BaseTools/Source/Python/GenFds/RuleComplexFile.py new file mode 100644 index 0000000000..63e65c5970 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/RuleComplexFile.py @@ -0,0 +1,30 @@ +## @file +# Complex Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Rule +from CommonDataClass.FdfClass import RuleComplexFileClassObject + +## complex rule +# +# +class RuleComplexFile(RuleComplexFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleComplexFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleSimpleFile.py b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py new file mode 100644 index 0000000000..c6fdbd88dc --- /dev/null +++ b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py @@ -0,0 +1,30 @@ +## @file +# Simple Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 Rule +from CommonDataClass.FdfClass import RuleSimpleFileClassObject + +## simple rule +# +# +class RuleSimpleFile (RuleSimpleFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleSimpleFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py new file mode 100644 index 0000000000..ffca3a11fe --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -0,0 +1,153 @@ +## @file +# section base class +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from CommonDataClass.FdfClass import SectionClassObject +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os, glob +from Common import EdkLogger +from Common.BuildToolError import * + +## section base class +# +# +class Section (SectionClassObject): + SectionType = { + 'RAW' : 'EFI_SECTION_RAW', + 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', + 'PE32' : 'EFI_SECTION_PE32', + 'PIC' : 'EFI_SECTION_PIC', + 'TE' : 'EFI_SECTION_TE', + 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 'DXE_DEPEX' : 'EFI_SECTION_DXE_DEPEX', + 'PEI_DEPEX' : 'EFI_SECTION_PEI_DEPEX', + 'GUIDED' : 'EFI_SECTION_GUID_DEFINED', + 'COMPRESS' : 'EFI_SECTION_COMPRESSION', + 'UI' : 'EFI_SECTION_USER_INTERFACE', + 'SMM_DEPEX' : 'EFI_SECTION_SMM_DEPEX' + } + + BinFileType = { + 'GUID' : '.guid', + 'ACPI' : '.acpi', + 'ASL' : '.asl' , + 'UEFI_APP' : '.app', + 'LIB' : '.lib', + 'PE32' : '.pe32', + 'PIC' : '.pic', + 'PEI_DEPEX' : '.depex', + 'SEC_PEI_DEPEX' : '.depex', + 'TE' : '.te', + 'UNI_VER' : '.ver', + 'VER' : '.ver', + 'UNI_UI' : '.ui', + 'UI' : '.ui', + 'BIN' : '.bin', + 'RAW' : '.raw', + 'COMPAT16' : '.comp16', + 'FV' : '.fv' + } + + SectFileType = { + 'SEC_GUID' : '.sec' , + 'SEC_PE32' : '.sec' , + 'SEC_PIC' : '.sec', + 'SEC_TE' : '.sec', + 'SEC_VER' : '.sec', + 'SEC_UI' : '.sec', + 'SEC_COMPAT16' : '.sec', + 'SEC_BIN' : '.sec' + } + + ToolGuid = { + '0xa31280ad-0x481e-0x41b6-0x95e8-0x127f-0x4c984779' : 'TianoCompress', + '0xee4e5898-0x3914-0x4259-0x9d6e-0xdc7b-0xd79403cf' : 'LzmaCompress' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + + ## GenSection() method + # + # virtual function + # + # @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 + # + def GenSection(self, OutputPath, GuidName, SecNum, keyStringList, FfsInf = None, Dict = {}): + pass + + ## GetFileList() method + # + # Generate compressed section + # + # @param self The object pointer + # @param FfsInf FfsInfStatement object that contains file list + # @param FileType File type to get + # @param FileExtension File extension to get + # @param Dict dictionary contains macro and its value + # @retval tuple (File list, boolean) + # + def GetFileList(FfsInf, FileType, FileExtension, Dict = {}): + if FileType in Section.SectFileType.keys() : + IsSect = True + else : + IsSect = False + + if FileExtension != None: + Suffix = FileExtension + elif IsSect : + Suffix = Section.SectionType.get(FileType) + else: + Suffix = Section.BinFileType.get(FileType) + if FfsInf == None: + EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!') + + FileList = [] + if FileType != None: + for File in FfsInf.BinFileList: + if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch: + if File.Type == FileType: + if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: + FileList.append(File.Path) + else: + GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName)) + else: + GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType)) + else: + GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName)) + + if Suffix != None and os.path.exists(FfsInf.EfiOutputPath): +# FileList.extend(glob.glob(os.path.join(FfsInf.EfiOutputPath, "*" + Suffix))) + # Update to search files with suffix in all sub-dirs. + Tuple = os.walk(FfsInf.EfiOutputPath) + for Dirpath, Dirnames, Filenames in Tuple: + for F in Filenames: + if os.path.splitext(F)[1] in (Suffix): + FullName = os.path.join(Dirpath, F) + FileList.append(FullName) + + return FileList, IsSect + GetFileList = staticmethod(GetFileList) diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py new file mode 100644 index 0000000000..e660055f9a --- /dev/null +++ b/BaseTools/Source/Python/GenFds/UiSection.py @@ -0,0 +1,77 @@ +## @file +# process UI section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +from Ffs import Ffs +import subprocess +import os +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import UiSectionClassObject + +## generate UI section +# +# +class UiSection (UiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + UiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate UI 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 = {}): + # + # Prepare the parameter of GenSection + # + if FfsInf != None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('UI')) + + if self.StringData != None : + NameString = self.StringData + elif self.FileName != None: + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + NameString = FileObj.read() + NameString = '\"' + NameString + "\"" + FileObj.close() + else: + NameString = '' + + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString) + + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py new file mode 100644 index 0000000000..e27d0a20f9 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/VerSection.py @@ -0,0 +1,82 @@ +## @file +# process Version section generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from Ffs import Ffs +import Section +import os +import subprocess +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import VerSectionClassObject + +## generate version section +# +# +class VerSection (VerSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + VerSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate version 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 = {}): + # + # Prepare the parameter of GenSection + # + if FfsInf != None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, + ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('VERSION')) + OutputFile = os.path.normpath(OutputFile) + + # Get String Data + StringData = '' + if self.StringData != None: + StringData = self.StringData + elif self.FileName != None: + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + StringData = FileObj.read() + StringData = '"' + StringData + '"' + FileObj.close() + else: + StringData = '' + + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_VERSION', + Ui=StringData, Ver=self.BuildNum) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/Vtf.py b/BaseTools/Source/Python/GenFds/Vtf.py new file mode 100644 index 0000000000..eebc7b1dab --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Vtf.py @@ -0,0 +1,188 @@ +## @file +# process VTF generation +# +# Copyright (c) 2007, Intel Corporation +# +# All rights reserved. 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 +# +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +from CommonDataClass.FdfClass import VtfClassObject +T_CHAR_LF = '\n' + +## generate VTF +# +# +class Vtf (VtfClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + VtfClassObject.__init__(self) + + ## GenVtf() method + # + # Generate VTF + # + # @param self The object pointer + # @param FdAddressDict dictionary contains FV name and its base address + # @retval Dict FV and corresponding VTF file name + # + def GenVtf(self, FdAddressDict) : + self.GenBsfInf() + OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.Vtf') + BaseAddArg = self.GetBaseAddressArg(FdAddressDict) + OutputArg, VtfRawDict = self.GenOutputArg() + + Cmd = ( + 'GenVtf', + ) + OutputArg + ( + '-f', self.BsfInfName, + ) + BaseAddArg + + GenFdsGlobalVariable.CallExternalTool(Cmd, "GenFv -Vtf Failed!") + GenFdsGlobalVariable.SharpCounter = 0 + + return VtfRawDict + + ## GenBsfInf() method + # + # Generate inf used to generate VTF + # + # @param self The object pointer + # + def GenBsfInf (self): + FvList = self.GetFvList() + self.BsfInfName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.inf') + BsfInf = open (self.BsfInfName, 'w+') + BsfInf.writelines ("[COMPONENTS]" + T_CHAR_LF) + + for ComponentObj in self.ComponentStatementList : + BsfInf.writelines ("COMP_NAME" + \ + " = " + \ + ComponentObj.CompName + \ + T_CHAR_LF ) + if ComponentObj.CompLoc.upper() == 'NONE': + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'N' + \ + T_CHAR_LF ) + + elif ComponentObj.FilePos != None: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + ComponentObj.FilePos + \ + T_CHAR_LF ) + else: + Index = FvList.index(ComponentObj.CompLoc.upper()) + if Index == 0: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'F' + \ + T_CHAR_LF ) + elif Index == 1: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'S' + \ + T_CHAR_LF ) + + BsfInf.writelines ("COMP_TYPE" + \ + " = " + \ + ComponentObj.CompType + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_VER" + \ + " = " + \ + ComponentObj.CompVer + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_CS" + \ + " = " + \ + ComponentObj.CompCs + \ + T_CHAR_LF ) + + BinPath = ComponentObj.CompBin + if BinPath != '-': + BinPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(BinPath)) + BsfInf.writelines ("COMP_BIN" + \ + " = " + \ + BinPath + \ + T_CHAR_LF ) + + SymPath = ComponentObj.CompSym + if SymPath != '-': + SymPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(SymPath)) + BsfInf.writelines ("COMP_SYM" + \ + " = " + \ + SymPath + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_SIZE" + \ + " = " + \ + ComponentObj.CompSize + \ + T_CHAR_LF ) + BsfInf.writelines (T_CHAR_LF ) + + BsfInf.close() + + ## GenFvList() method + # + # Get FV list referenced by VTF components + # + # @param self The object pointer + # + def GetFvList(self): + FvList = [] + for component in self.ComponentStatementList : + if component.CompLoc.upper() != 'NONE' and not (component.CompLoc.upper() in FvList): + FvList.append(component.CompLoc.upper()) + + return FvList + + ## GetBaseAddressArg() method + # + # Get base address arguments for GenVtf + # + # @param self The object pointer + # + def GetBaseAddressArg(self, FdAddressDict): + FvList = self.GetFvList() + CmdStr = tuple() + for i in FvList: + (BaseAddress, Size) = FdAddressDict.get(i) + CmdStr += ( + '-r', '0x%x' % BaseAddress, + '-s', '0x%x' %Size, + ) + return CmdStr + + ## GenOutputArg() method + # + # Get output arguments for GenVtf + # + # @param self The object pointer + # + def GenOutputArg(self): + FvVtfDict = {} + OutputFileName = '' + FvList = self.GetFvList() + Index = 0 + Arg = tuple() + for FvObj in FvList: + Index = Index + 1 + OutputFileName = 'Vtf%d.raw' % Index + OutputFileName = os.path.join(GenFdsGlobalVariable.FvDir, OutputFileName) + Arg += ('-o', OutputFileName) + FvVtfDict[FvObj.upper()] = OutputFileName + + return Arg, FvVtfDict + diff --git a/BaseTools/Source/Python/GenFds/__init__.py b/BaseTools/Source/Python/GenFds/__init__.py new file mode 100644 index 0000000000..e69de29bb2 -- cgit v1.2.3