From: "Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>
To: Patrick Georgi <pgeorgi@google.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH 3/3] IntelFsp2Pkg: Tell git to format SplitFspBin.py with native newlines
Date: Tue, 18 Sep 2018 15:10:31 +0000 [thread overview]
Message-ID: <5608C728-C8C9-4D20-8C4D-FEC4FA974BA6@intel.com> (raw)
In-Reply-To: <20180918133203.192779-3-pgeorgi@google.com>
Hi Patrick,
The EDK2 coding standard specifies that all files should be in CR-LF format. Please see the following: https://edk2-docs.gitbooks.io/edk-ii-c-coding-standards-specification/content/5_source_files/#51-general-rules
Is the .gitattributes file alone sufficient?
Thanks,
Nate
On 9/18/18, 6:32 AM, "edk2-devel on behalf of Patrick Georgi" <edk2-devel-bounces@lists.01.org on behalf of pgeorgi@google.com> wrote:
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Contributed-under: TianoCore Contribution Agreement 1.1
---
IntelFsp2Pkg/Tools/.gitattributes | 1 +
IntelFsp2Pkg/Tools/SplitFspBin.py | 1708 ++++++++++++++---------------
2 files changed, 855 insertions(+), 854 deletions(-)
create mode 100644 IntelFsp2Pkg/Tools/.gitattributes
diff --git a/IntelFsp2Pkg/Tools/.gitattributes b/IntelFsp2Pkg/Tools/.gitattributes
new file mode 100644
index 0000000000..0f876007cd
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/.gitattributes
@@ -0,0 +1 @@
+SplitFspBin.py text
diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py
index ac864492e8..5f1fab071f 100755
--- a/IntelFsp2Pkg/Tools/SplitFspBin.py
+++ b/IntelFsp2Pkg/Tools/SplitFspBin.py
@@ -1,854 +1,854 @@
-#!/usr/bin/env python
-## @ FspTool.py
-#
-# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials are licensed and made available under
-# the terms and conditions of the BSD License that 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 os
-import sys
-import uuid
-import copy
-import struct
-import argparse
-from ctypes import *
-
-"""
-This utility supports some operations for Intel FSP 2.0 image.
-It supports:
- - Display FSP 2.0 information header
- - Split FSP 2.0 image into individual FSP-T/M/S/O component
- - Rebase FSP 2.0 components to a different base address
- - Generate FSP mapping C header file
-"""
-
-CopyRightHeaderFile = """/*
- *
- * Automatically generated file; DO NOT EDIT.
- * FSP mapping file
- *
- */
-"""
-
-class c_uint24(Structure):
- """Little-Endian 24-bit Unsigned Integer"""
- _pack_ = 1
- _fields_ = [('Data', (c_uint8 * 3))]
-
- def __init__(self, val=0):
- self.set_value(val)
-
- def __str__(self, indent=0):
- return '0x%.6x' % self.value
-
- def __int__(self):
- return self.get_value()
-
- def set_value(self, val):
- self.Data[0:3] = Val2Bytes(val, 3)
-
- def get_value(self):
- return Bytes2Val(self.Data[0:3])
-
- value = property(get_value, set_value)
-
-class EFI_FIRMWARE_VOLUME_HEADER(Structure):
- _fields_ = [
- ('ZeroVector', ARRAY(c_uint8, 16)),
- ('FileSystemGuid', ARRAY(c_uint8, 16)),
- ('FvLength', c_uint64),
- ('Signature', ARRAY(c_char, 4)),
- ('Attributes', c_uint32),
- ('HeaderLength', c_uint16),
- ('Checksum', c_uint16),
- ('ExtHeaderOffset', c_uint16),
- ('Reserved', c_uint8),
- ('Revision', c_uint8)
- ]
-
-class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
- _fields_ = [
- ('FvName', ARRAY(c_uint8, 16)),
- ('ExtHeaderSize', c_uint32)
- ]
-
-class EFI_FFS_INTEGRITY_CHECK(Structure):
- _fields_ = [
- ('Header', c_uint8),
- ('File', c_uint8)
- ]
-
-class EFI_FFS_FILE_HEADER(Structure):
- _fields_ = [
- ('Name', ARRAY(c_uint8, 16)),
- ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
- ('Type', c_uint8),
- ('Attributes', c_uint8),
- ('Size', c_uint24),
- ('State', c_uint8)
- ]
-
-class EFI_COMMON_SECTION_HEADER(Structure):
- _fields_ = [
- ('Size', c_uint24),
- ('Type', c_uint8)
- ]
-
-class FSP_COMMON_HEADER(Structure):
- _fields_ = [
- ('Signature', ARRAY(c_char, 4)),
- ('HeaderLength', c_uint32)
- ]
-
-class FSP_INFORMATION_HEADER(Structure):
- _fields_ = [
- ('Signature', ARRAY(c_char, 4)),
- ('HeaderLength', c_uint32),
- ('Reserved1', c_uint16),
- ('SpecVersion', c_uint8),
- ('HeaderRevision', c_uint8),
- ('ImageRevision', c_uint32),
- ('ImageId', ARRAY(c_char, 8)),
- ('ImageSize', c_uint32),
- ('ImageBase', c_uint32),
- ('ImageAttribute', c_uint16),
- ('ComponentAttribute', c_uint16),
- ('CfgRegionOffset', c_uint32),
- ('CfgRegionSize', c_uint32),
- ('Reserved2', c_uint32),
- ('TempRamInitEntryOffset', c_uint32),
- ('Reserved3', c_uint32),
- ('NotifyPhaseEntryOffset', c_uint32),
- ('FspMemoryInitEntryOffset', c_uint32),
- ('TempRamExitEntryOffset', c_uint32),
- ('FspSiliconInitEntryOffset', c_uint32)
- ]
-
-class FSP_PATCH_TABLE(Structure):
- _fields_ = [
- ('Signature', ARRAY(c_char, 4)),
- ('HeaderLength', c_uint16),
- ('HeaderRevision', c_uint8),
- ('Reserved', c_uint8),
- ('PatchEntryNum', c_uint32)
- ]
-
-class EFI_IMAGE_DATA_DIRECTORY(Structure):
- _fields_ = [
- ('VirtualAddress', c_uint32),
- ('Size', c_uint32)
- ]
-
-class EFI_TE_IMAGE_HEADER(Structure):
- _fields_ = [
- ('Signature', ARRAY(c_char, 2)),
- ('Machine', c_uint16),
- ('NumberOfSections', c_uint8),
- ('Subsystem', c_uint8),
- ('StrippedSize', c_uint16),
- ('AddressOfEntryPoint', c_uint32),
- ('BaseOfCode', c_uint32),
- ('ImageBase', c_uint64),
- ('DataDirectoryBaseReloc', EFI_IMAGE_DATA_DIRECTORY),
- ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
- ]
-
-class EFI_IMAGE_DOS_HEADER(Structure):
- _fields_ = [
- ('e_magic', c_uint16),
- ('e_cblp', c_uint16),
- ('e_cp', c_uint16),
- ('e_crlc', c_uint16),
- ('e_cparhdr', c_uint16),
- ('e_minalloc', c_uint16),
- ('e_maxalloc', c_uint16),
- ('e_ss', c_uint16),
- ('e_sp', c_uint16),
- ('e_csum', c_uint16),
- ('e_ip', c_uint16),
- ('e_cs', c_uint16),
- ('e_lfarlc', c_uint16),
- ('e_ovno', c_uint16),
- ('e_res', ARRAY(c_uint16, 4)),
- ('e_oemid', c_uint16),
- ('e_oeminfo', c_uint16),
- ('e_res2', ARRAY(c_uint16, 10)),
- ('e_lfanew', c_uint16)
- ]
-
-class EFI_IMAGE_FILE_HEADER(Structure):
- _fields_ = [
- ('Machine', c_uint16),
- ('NumberOfSections', c_uint16),
- ('TimeDateStamp', c_uint32),
- ('PointerToSymbolTable', c_uint32),
- ('NumberOfSymbols', c_uint32),
- ('SizeOfOptionalHeader', c_uint16),
- ('Characteristics', c_uint16)
- ]
-
-class PE_RELOC_BLOCK_HEADER(Structure):
- _fields_ = [
- ('PageRVA', c_uint32),
- ('BlockSize', c_uint32)
- ]
-
-class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
- _fields_ = [
- ('Magic', c_uint16),
- ('MajorLinkerVersion', c_uint8),
- ('MinorLinkerVersion', c_uint8),
- ('SizeOfCode', c_uint32),
- ('SizeOfInitializedData', c_uint32),
- ('SizeOfUninitializedData', c_uint32),
- ('AddressOfEntryPoint', c_uint32),
- ('BaseOfCode', c_uint32),
- ('BaseOfData', c_uint32),
- ('ImageBase', c_uint32),
- ('SectionAlignment', c_uint32),
- ('FileAlignment', c_uint32),
- ('MajorOperatingSystemVersion', c_uint16),
- ('MinorOperatingSystemVersion', c_uint16),
- ('MajorImageVersion', c_uint16),
- ('MinorImageVersion', c_uint16),
- ('MajorSubsystemVersion', c_uint16),
- ('MinorSubsystemVersion', c_uint16),
- ('Win32VersionValue', c_uint32),
- ('SizeOfImage', c_uint32),
- ('SizeOfHeaders', c_uint32),
- ('CheckSum' , c_uint32),
- ('Subsystem', c_uint16),
- ('DllCharacteristics', c_uint16),
- ('SizeOfStackReserve', c_uint32),
- ('SizeOfStackCommit' , c_uint32),
- ('SizeOfHeapReserve', c_uint32),
- ('SizeOfHeapCommit' , c_uint32),
- ('LoaderFlags' , c_uint32),
- ('NumberOfRvaAndSizes', c_uint32),
- ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
- ]
-
-class EFI_IMAGE_OPTIONAL_HEADER32_PLUS(Structure):
- _fields_ = [
- ('Magic', c_uint16),
- ('MajorLinkerVersion', c_uint8),
- ('MinorLinkerVersion', c_uint8),
- ('SizeOfCode', c_uint32),
- ('SizeOfInitializedData', c_uint32),
- ('SizeOfUninitializedData', c_uint32),
- ('AddressOfEntryPoint', c_uint32),
- ('BaseOfCode', c_uint32),
- ('ImageBase', c_uint64),
- ('SectionAlignment', c_uint32),
- ('FileAlignment', c_uint32),
- ('MajorOperatingSystemVersion', c_uint16),
- ('MinorOperatingSystemVersion', c_uint16),
- ('MajorImageVersion', c_uint16),
- ('MinorImageVersion', c_uint16),
- ('MajorSubsystemVersion', c_uint16),
- ('MinorSubsystemVersion', c_uint16),
- ('Win32VersionValue', c_uint32),
- ('SizeOfImage', c_uint32),
- ('SizeOfHeaders', c_uint32),
- ('CheckSum' , c_uint32),
- ('Subsystem', c_uint16),
- ('DllCharacteristics', c_uint16),
- ('SizeOfStackReserve', c_uint64),
- ('SizeOfStackCommit' , c_uint64),
- ('SizeOfHeapReserve', c_uint64),
- ('SizeOfHeapCommit' , c_uint64),
- ('LoaderFlags' , c_uint32),
- ('NumberOfRvaAndSizes', c_uint32),
- ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
- ]
-
-class EFI_IMAGE_OPTIONAL_HEADER(Union):
- _fields_ = [
- ('PeOptHdr', EFI_IMAGE_OPTIONAL_HEADER32),
- ('PePlusOptHdr', EFI_IMAGE_OPTIONAL_HEADER32_PLUS)
- ]
-
-class EFI_IMAGE_NT_HEADERS32(Structure):
- _fields_ = [
- ('Signature', c_uint32),
- ('FileHeader', EFI_IMAGE_FILE_HEADER),
- ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER)
- ]
-
-
-class EFI_IMAGE_DIRECTORY_ENTRY:
- EXPORT = 0
- IMPORT = 1
- RESOURCE = 2
- EXCEPTION = 3
- SECURITY = 4
- BASERELOC = 5
- DEBUG = 6
- COPYRIGHT = 7
- GLOBALPTR = 8
- TLS = 9
- LOAD_CONFIG = 10
-
-class EFI_FV_FILETYPE:
- ALL = 0x00
- RAW = 0x01
- FREEFORM = 0x02
- SECURITY_CORE = 0x03
- PEI_CORE = 0x04
- DXE_CORE = 0x05
- PEIM = 0x06
- DRIVER = 0x07
- COMBINED_PEIM_DRIVER = 0x08
- APPLICATION = 0x09
- SMM = 0x0a
- FIRMWARE_VOLUME_IMAGE = 0x0b
- COMBINED_SMM_DXE = 0x0c
- SMM_CORE = 0x0d
- OEM_MIN = 0xc0
- OEM_MAX = 0xdf
- DEBUG_MIN = 0xe0
- DEBUG_MAX = 0xef
- FFS_MIN = 0xf0
- FFS_MAX = 0xff
- FFS_PAD = 0xf0
-
-class EFI_SECTION_TYPE:
- """Enumeration of all valid firmware file section types."""
- ALL = 0x00
- COMPRESSION = 0x01
- GUID_DEFINED = 0x02
- DISPOSABLE = 0x03
- PE32 = 0x10
- PIC = 0x11
- TE = 0x12
- DXE_DEPEX = 0x13
- VERSION = 0x14
- USER_INTERFACE = 0x15
- COMPATIBILITY16 = 0x16
- FIRMWARE_VOLUME_IMAGE = 0x17
- FREEFORM_SUBTYPE_GUID = 0x18
- RAW = 0x19
- PEI_DEPEX = 0x1b
- SMM_DEPEX = 0x1c
-
-def AlignPtr (offset, alignment = 8):
- return (offset + alignment - 1) & ~(alignment - 1)
-
-def Bytes2Val (bytes):
- return reduce(lambda x,y: (x<<8)|y, bytes[::-1] )
-
-def Val2Bytes (value, blen):
- return [(value>>(i*8) & 0xff) for i in range(blen)]
-
-def OutputStruct (obj, indent = 0, plen = 0):
- if indent:
- body = ''
- else:
- body = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
-
- if plen == 0:
- plen = sizeof(obj)
-
- max_key_len = 26
- pstr = (' ' * (indent + 1) + '{0:<%d} = {1}\n') % max_key_len
-
- for field in obj._fields_:
- key = field[0]
- val = getattr(obj, key)
- rep = ''
- if not isinstance(val, c_uint24) and isinstance(val, Structure):
- body += pstr.format(key, val.__class__.__name__)
- body += OutputStruct (val, indent + 1)
- plen -= sizeof(val)
- else:
- if type(val) is str:
- rep = "0x%X ('%s')" % (Bytes2Val(bytearray(val)), val)
- elif type(val) in (int, long):
- rep = '0x%X' % val
- elif isinstance(val, c_uint24):
- rep = '0x%X' % val.get_value()
- elif 'c_ubyte_Array' in str(type(val)):
- if sizeof(val) == 16:
- rep = str(uuid.UUID(bytes = str(bytearray(val)))).upper()
- else:
- res = ['0x%02X'%i for i in bytearray(val)]
- rep = '[%s]' % (','.join(res))
- else:
- rep = str(val)
- plen -= sizeof(field[1])
- body += pstr.format(key, rep)
- if plen <= 0:
- break
- return body
-
-class Section:
- def __init__(self, offset, secdata):
- self.SecHdr = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
- self.SecData = secdata[0:int(self.SecHdr.Size)]
- self.Offset = offset
-
-class FirmwareFile:
- def __init__(self, offset, filedata):
- self.FfsHdr = EFI_FFS_FILE_HEADER.from_buffer (filedata, 0)
- self.FfsData = filedata[0:int(self.FfsHdr.Size)]
- self.Offset = offset
- self.SecList = []
-
- def ParseFfs(self):
- ffssize = len(self.FfsData)
- offset = sizeof(self.FfsHdr)
- if self.FfsHdr.Name != '\xff' * 16:
- while offset < ffssize:
- sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
- sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
- self.SecList.append(sec)
- offset += int(sechdr.Size)
- offset = AlignPtr(offset, 4)
-
-class FirmwareVolume:
- def __init__(self, offset, fvdata):
- self.FvHdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (fvdata, 0)
- self.FvData = fvdata[0 : self.FvHdr.FvLength]
- self.Offset = offset
- if self.FvHdr.ExtHeaderOffset > 0:
- self.FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FvData, self.FvHdr.ExtHeaderOffset)
- else:
- self.FvExtHdr = None
- self.FfsList = []
-
- def ParseFv(self):
- fvsize = len(self.FvData)
- if self.FvExtHdr:
- offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
- else:
- offset = self.FvHdr.HeaderLength
- offset = AlignPtr(offset)
- while offset < fvsize:
- ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
- if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
- offset = fvsize
- else:
- ffs = FirmwareFile (offset, self.FvData[offset:offset + int(ffshdr.Size)])
- ffs.ParseFfs()
- self.FfsList.append(ffs)
- offset += int(ffshdr.Size)
- offset = AlignPtr(offset)
-
-class FspImage:
- def __init__(self, offset, fih, fihoff, patch):
- self.Fih = fih
- self.FihOffset = fihoff
- self.Offset = offset
- self.FvIdxList = []
- self.Type = "XTMSXXXXOXXXXXXX"[(fih.ComponentAttribute >> 12) & 0x0F]
- self.PatchList = patch
- self.PatchList.append(fihoff + 0x1C)
-
- def AppendFv(self, FvIdx):
- self.FvIdxList.append(FvIdx)
-
- def Patch(self, delta, fdbin):
- count = 0
- applied = 0
- for idx, patch in enumerate(self.PatchList):
- ptype = (patch>>24) & 0x0F
- if ptype not in [0x00, 0x0F]:
- raise Exception('ERROR: Invalid patch type %d !' % ptype)
- if patch & 0x80000000:
- patch = self.Fih.ImageSize - (0x1000000 - (patch & 0xFFFFFF))
- else:
- patch = patch & 0xFFFFFF
- if (patch < self.Fih.ImageSize) and (patch + sizeof(c_uint32) <= self.Fih.ImageSize):
- offset = patch + self.Offset
- value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
- value += delta
- fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
- applied += 1
- count += 1
- # Don't count the FSP base address patch entry appended at the end
- if count != 0:
- count -= 1
- applied -= 1
- return (count, applied)
-
-class FirmwareDevice:
- def __init__(self, offset, fdfile):
- self.FvList = []
- self.FspList = []
- self.FdFile = fdfile
- self.Offset = 0
- hfsp = open (self.FdFile, 'rb')
- self.FdData = bytearray(hfsp.read())
- hfsp.close()
-
- def ParseFd(self):
- offset = 0
- fdsize = len(self.FdData)
- self.FvList = []
- while offset < fdsize:
- fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
- if '_FVH' != fvh.Signature:
- raise Exception("ERROR: Invalid FV header !")
- fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
- fv.ParseFv ()
- self.FvList.append(fv)
- offset += fv.FvHdr.FvLength
-
- def CheckFsp (self):
- if len(self.FspList) == 0:
- return
-
- fih = None
- for fsp in self.FspList:
- if fsp.Fih.HeaderRevision < 3:
- raise Exception("ERROR: FSP 1.x is not supported by this tool !")
- if not fih:
- fih = fsp.Fih
- else:
- newfih = fsp.Fih
- if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
- raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
-
- def ParseFsp(self):
- flen = 0
- for idx, fv in enumerate(self.FvList):
- # Check if this FV contains FSP header
- if flen == 0:
- if len(fv.FfsList) == 0:
- continue
- ffs = fv.FfsList[0]
- if len(ffs.SecList) == 0:
- continue
- sec = ffs.SecList[0]
- if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
- continue
- fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
- fspoffset = fv.Offset
- offset = fspoffset + fihoffset
- fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
- if 'FSPH' != fih.Signature:
- continue
-
- offset += fih.HeaderLength
- offset = AlignPtr(offset, 4)
- plist = []
- while True:
- fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)
- if 'FSPP' != fch.Signature:
- offset += fch.HeaderLength
- offset = AlignPtr(offset, 4)
- else:
- fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)
- offset += sizeof(fspp)
- pdata = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)
- plist = list(pdata)
- break
-
- fsp = FspImage (fspoffset, fih, fihoffset, plist)
- fsp.AppendFv (idx)
- self.FspList.append(fsp)
- flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength
- else:
- fsp.AppendFv (idx)
- flen -= fv.FvHdr.FvLength
- if flen < 0:
- raise Exception("ERROR: Incorrect FV size in image !")
- self.CheckFsp ()
-
-class PeTeImage:
- def __init__(self, offset, data):
- self.Offset = offset
- tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
- if tehdr.Signature == 'VZ': # TE image
- self.TeHdr = tehdr
- elif tehdr.Signature == 'MZ': # PE image
- self.TeHdr = None
- self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
- self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
- if self.PeHdr.Signature != 0x4550:
- raise Exception("ERROR: Invalid PE32 header !")
- if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
- if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
- raise Exception("ERROR: Unsupported PE32 image !")
- if self.PeHdr.OptionalHeader.PeOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
- raise Exception("ERROR: No relocation information available !")
- elif self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
- if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32_PLUS.DataDirectory.offset:
- raise Exception("ERROR: Unsupported PE32+ image !")
- if self.PeHdr.OptionalHeader.PePlusOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
- raise Exception("ERROR: No relocation information available !")
- else:
- raise Exception("ERROR: Invalid PE32 optional header !")
- self.Offset = offset
- self.Data = data
- self.RelocList = []
-
- def IsTeImage(self):
- return self.TeHdr is not None
-
- def ParseReloc(self):
- if self.IsTeImage():
- rsize = self.TeHdr.DataDirectoryBaseReloc.Size
- roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
- else:
- if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
- rsize = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
- roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
- if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
- rsize = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
- roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
-
- alignment = 4
- offset = roffset
- while offset < roffset + rsize:
- offset = AlignPtr(offset, 4)
- blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
- offset += sizeof(blkhdr)
- # Read relocation type,offset pairs
- rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
- rnum = rlen/sizeof(c_uint16)
- rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
- for each in rdata:
- roff = each & 0xfff
- rtype = each >> 12
- if rtype == 0: # IMAGE_REL_BASED_ABSOLUTE:
- continue
- if ((rtype != 3) and (rtype != 10)): # IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64
- raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
- # Calculate the offset of the relocation
- aoff = blkhdr.PageRVA + roff
- if self.IsTeImage():
- aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
- self.RelocList.append((rtype, aoff))
- offset += sizeof(rdata)
-
- def Rebase(self, delta, fdbin):
- count = 0
- if delta == 0:
- return count
-
- for (rtype, roff) in self.RelocList:
- if rtype == 3: # IMAGE_REL_BASED_HIGHLOW
- offset = roff + self.Offset
- value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
- value += delta
- fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
- count += 1
- elif rtype == 10: # IMAGE_REL_BASED_DIR64
- offset = roff + self.Offset
- value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint64)])
- value += delta
- fdbin[offset:offset+sizeof(c_uint64)] = Val2Bytes(value, sizeof(c_uint64))
- count += 1
- else:
- raise Exception('ERROR: Unknown relocation type %d !' % rtype)
-
- if self.IsTeImage():
- offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
- size = EFI_TE_IMAGE_HEADER.ImageBase.size
- else:
- offset = self.Offset + self.DosHdr.e_lfanew
- offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
- offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
- size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
-
- value = Bytes2Val(fdbin[offset:offset+size]) + delta
- fdbin[offset:offset+size] = Val2Bytes(value, size)
-
- return count
-
-def ShowFspInfo (fspfile):
- fd = FirmwareDevice(0, fspfile)
- fd.ParseFd ()
- fd.ParseFsp ()
-
- print ("\nFound the following %d Firmware Volumes in FSP binary:" % (len(fd.FvList)))
- for idx, fv in enumerate(fd.FvList):
- name = fv.FvExtHdr.FvName
- if not name:
- name = '\xff' * 16
- else:
- name = str(bytearray(name))
- guid = uuid.UUID(bytes = name)
- print ("FV%d:" % idx)
- print (" GUID : %s" % str(guid).upper())
- print (" Offset : 0x%08X" % fv.Offset)
- print (" Length : 0x%08X" % fv.FvHdr.FvLength)
- print ("\n")
-
- for fsp in fd.FspList:
- fvlist = map(lambda x : 'FV%d' % x, fsp.FvIdxList)
- print ("FSP_%s contains %s" % (fsp.Type, ','.join(fvlist)))
- print ("%s" % (OutputStruct(fsp.Fih, 0, fsp.Fih.HeaderLength)))
-
-def GenFspHdr (fspfile, outdir, hfile):
- fd = FirmwareDevice(0, fspfile)
- fd.ParseFd ()
- fd.ParseFsp ()
-
- if not hfile:
- hfile = os.path.splitext(os.path.basename(fspfile))[0] + '.h'
- fspname, ext = os.path.splitext(os.path.basename(hfile))
- filename = os.path.join(outdir, fspname + ext)
- hfsp = open(filename, 'w')
- hfsp.write ('%s\n\n' % CopyRightHeaderFile)
-
- firstfv = True
- for fsp in fd.FspList:
- fih = fsp.Fih
- if firstfv:
- hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
- hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
- firstfv = False
- fv = fd.FvList[fsp.FvIdxList[0]]
- hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp.Type, fih.ImageBase))
- hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp.Type, fv.Offset))
- hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp.Type, fih.ImageSize))
-
- hfsp.close()
-
-def SplitFspBin (fspfile, outdir, nametemplate):
- fd = FirmwareDevice(0, fspfile)
- fd.ParseFd ()
- fd.ParseFsp ()
-
- for fsp in fd.FspList:
- ftype = fsp.Type
- if not nametemplate:
- nametemplate = fspfile
- fspname, ext = os.path.splitext(os.path.basename(nametemplate))
- filename = os.path.join(outdir, fspname + '_' + fsp.Type + ext)
- hfsp = open(filename, 'wb')
- print ("Create FSP component file '%s'" % filename)
- for fvidx in fsp.FvIdxList:
- fv = fd.FvList[fvidx]
- hfsp.write(fv.FvData)
- hfsp.close()
-
-def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
- fd = FirmwareDevice(0, FspBinary)
- fd.ParseFd ()
- fd.ParseFsp ()
-
- numcomp = len(FspComponent)
- baselist = FspBase
- if numcomp != len(baselist):
- print "ERROR: Required number of base does not match number of FSP component !"
- return
-
- newfspbin = fd.FdData[:]
-
- for idx, fspcomp in enumerate(FspComponent):
-
- found = False
- for fsp in fd.FspList:
- ftype = fsp.Type.lower()
- if ftype == fspcomp:
- found = True
- break
-
- if not found:
- print "ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper()
- return
-
- fspbase = baselist[idx]
- if fspbase.startswith('0x'):
- newbase = int(fspbase, 16)
- else:
- newbase = int(fspbase)
- oldbase = fsp.Fih.ImageBase
- delta = newbase - oldbase
- print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
-
- imglist = []
- for fvidx in fsp.FvIdxList:
- fv = fd.FvList[fvidx]
- for ffs in fv.FfsList:
- for sec in ffs.SecList:
- if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32
- offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
- imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
-
- fcount = 0
- pcount = 0
- for (offset, length) in imglist:
- img = PeTeImage(offset, fd.FdData[offset:offset + length])
- img.ParseReloc()
- pcount += img.Rebase(delta, newfspbin)
- fcount += 1
-
- print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
-
- (count, applied) = fsp.Patch(delta, newfspbin)
- print " Patched %d entries using FSP patch table." % applied
- if count != applied:
- print " %d invalid entries are ignored !" % (count - applied)
-
- if OutputFile == '':
- filename = os.path.basename(FspBinary)
- base, ext = os.path.splitext(filename)
- OutputFile = base + "_%08X" % newbase + ext
-
- fspname, ext = os.path.splitext(os.path.basename(OutputFile))
- filename = os.path.join(OutputDir, fspname + ext)
- fd = open(filename, "wb")
- fd.write(newfspbin)
- fd.close()
-
-def main ():
- parser = argparse.ArgumentParser()
- subparsers = parser.add_subparsers(title='commands')
-
- parser_rebase = subparsers.add_parser('rebase', help='rebase a FSP into a new base address')
- parser_rebase.set_defaults(which='rebase')
- parser_rebase.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
- parser_rebase.add_argument('-c', '--fspcomp', choices=['t','m','s','o'], nargs='+', dest='FspComponent', type=str, help='FSP component to rebase', default = "['t']", required = True)
- parser_rebase.add_argument('-b', '--newbase', dest='FspBase', nargs='+', type=str, help='Rebased FSP binary file name', default = '', required = True)
- parser_rebase.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
- parser_rebase.add_argument('-n', '--outfile', dest='OutputFile', type=str, help='Rebased FSP binary file name', default = '')
-
- parser_split = subparsers.add_parser('split', help='split a FSP into multiple components')
- parser_split.set_defaults(which='split')
- parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
- parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
- parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
-
- parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
- parser_genhdr.set_defaults(which='genhdr')
- parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
- parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
- parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '')
-
- parser_info = subparsers.add_parser('info', help='display FSP information')
- parser_info.set_defaults(which='info')
- parser_info.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
-
- args = parser.parse_args()
- if args.which in ['rebase', 'split', 'genhdr', 'info']:
- if not os.path.exists(args.FspBinary):
- raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
- if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
- raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
-
- if args.which == 'rebase':
- RebaseFspBin (args.FspBinary, args.FspComponent, args.FspBase, args.OutputDir, args.OutputFile)
- elif args.which == 'split':
- SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate)
- elif args.which == 'genhdr':
- GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
- elif args.which == 'info':
- ShowFspInfo (args.FspBinary)
- else:
- pass
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
+#!/usr/bin/env python
+## @ FspTool.py
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that 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 os
+import sys
+import uuid
+import copy
+import struct
+import argparse
+from ctypes import *
+
+"""
+This utility supports some operations for Intel FSP 2.0 image.
+It supports:
+ - Display FSP 2.0 information header
+ - Split FSP 2.0 image into individual FSP-T/M/S/O component
+ - Rebase FSP 2.0 components to a different base address
+ - Generate FSP mapping C header file
+"""
+
+CopyRightHeaderFile = """/*
+ *
+ * Automatically generated file; DO NOT EDIT.
+ * FSP mapping file
+ *
+ */
+"""
+
+class c_uint24(Structure):
+ """Little-Endian 24-bit Unsigned Integer"""
+ _pack_ = 1
+ _fields_ = [('Data', (c_uint8 * 3))]
+
+ def __init__(self, val=0):
+ self.set_value(val)
+
+ def __str__(self, indent=0):
+ return '0x%.6x' % self.value
+
+ def __int__(self):
+ return self.get_value()
+
+ def set_value(self, val):
+ self.Data[0:3] = Val2Bytes(val, 3)
+
+ def get_value(self):
+ return Bytes2Val(self.Data[0:3])
+
+ value = property(get_value, set_value)
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', ARRAY(c_uint8, 16)),
+ ('FvLength', c_uint64),
+ ('Signature', ARRAY(c_char, 4)),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
+ _fields_ = [
+ ('FvName', ARRAY(c_uint8, 16)),
+ ('ExtHeaderSize', c_uint32)
+ ]
+
+class EFI_FFS_INTEGRITY_CHECK(Structure):
+ _fields_ = [
+ ('Header', c_uint8),
+ ('File', c_uint8)
+ ]
+
+class EFI_FFS_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Name', ARRAY(c_uint8, 16)),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', c_uint24),
+ ('State', c_uint8)
+ ]
+
+class EFI_COMMON_SECTION_HEADER(Structure):
+ _fields_ = [
+ ('Size', c_uint24),
+ ('Type', c_uint8)
+ ]
+
+class FSP_COMMON_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint32)
+ ]
+
+class FSP_INFORMATION_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint32),
+ ('Reserved1', c_uint16),
+ ('SpecVersion', c_uint8),
+ ('HeaderRevision', c_uint8),
+ ('ImageRevision', c_uint32),
+ ('ImageId', ARRAY(c_char, 8)),
+ ('ImageSize', c_uint32),
+ ('ImageBase', c_uint32),
+ ('ImageAttribute', c_uint16),
+ ('ComponentAttribute', c_uint16),
+ ('CfgRegionOffset', c_uint32),
+ ('CfgRegionSize', c_uint32),
+ ('Reserved2', c_uint32),
+ ('TempRamInitEntryOffset', c_uint32),
+ ('Reserved3', c_uint32),
+ ('NotifyPhaseEntryOffset', c_uint32),
+ ('FspMemoryInitEntryOffset', c_uint32),
+ ('TempRamExitEntryOffset', c_uint32),
+ ('FspSiliconInitEntryOffset', c_uint32)
+ ]
+
+class FSP_PATCH_TABLE(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint16),
+ ('HeaderRevision', c_uint8),
+ ('Reserved', c_uint8),
+ ('PatchEntryNum', c_uint32)
+ ]
+
+class EFI_IMAGE_DATA_DIRECTORY(Structure):
+ _fields_ = [
+ ('VirtualAddress', c_uint32),
+ ('Size', c_uint32)
+ ]
+
+class EFI_TE_IMAGE_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 2)),
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint8),
+ ('Subsystem', c_uint8),
+ ('StrippedSize', c_uint16),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('ImageBase', c_uint64),
+ ('DataDirectoryBaseReloc', EFI_IMAGE_DATA_DIRECTORY),
+ ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
+ ]
+
+class EFI_IMAGE_DOS_HEADER(Structure):
+ _fields_ = [
+ ('e_magic', c_uint16),
+ ('e_cblp', c_uint16),
+ ('e_cp', c_uint16),
+ ('e_crlc', c_uint16),
+ ('e_cparhdr', c_uint16),
+ ('e_minalloc', c_uint16),
+ ('e_maxalloc', c_uint16),
+ ('e_ss', c_uint16),
+ ('e_sp', c_uint16),
+ ('e_csum', c_uint16),
+ ('e_ip', c_uint16),
+ ('e_cs', c_uint16),
+ ('e_lfarlc', c_uint16),
+ ('e_ovno', c_uint16),
+ ('e_res', ARRAY(c_uint16, 4)),
+ ('e_oemid', c_uint16),
+ ('e_oeminfo', c_uint16),
+ ('e_res2', ARRAY(c_uint16, 10)),
+ ('e_lfanew', c_uint16)
+ ]
+
+class EFI_IMAGE_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint16),
+ ('TimeDateStamp', c_uint32),
+ ('PointerToSymbolTable', c_uint32),
+ ('NumberOfSymbols', c_uint32),
+ ('SizeOfOptionalHeader', c_uint16),
+ ('Characteristics', c_uint16)
+ ]
+
+class PE_RELOC_BLOCK_HEADER(Structure):
+ _fields_ = [
+ ('PageRVA', c_uint32),
+ ('BlockSize', c_uint32)
+ ]
+
+class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
+ _fields_ = [
+ ('Magic', c_uint16),
+ ('MajorLinkerVersion', c_uint8),
+ ('MinorLinkerVersion', c_uint8),
+ ('SizeOfCode', c_uint32),
+ ('SizeOfInitializedData', c_uint32),
+ ('SizeOfUninitializedData', c_uint32),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('BaseOfData', c_uint32),
+ ('ImageBase', c_uint32),
+ ('SectionAlignment', c_uint32),
+ ('FileAlignment', c_uint32),
+ ('MajorOperatingSystemVersion', c_uint16),
+ ('MinorOperatingSystemVersion', c_uint16),
+ ('MajorImageVersion', c_uint16),
+ ('MinorImageVersion', c_uint16),
+ ('MajorSubsystemVersion', c_uint16),
+ ('MinorSubsystemVersion', c_uint16),
+ ('Win32VersionValue', c_uint32),
+ ('SizeOfImage', c_uint32),
+ ('SizeOfHeaders', c_uint32),
+ ('CheckSum' , c_uint32),
+ ('Subsystem', c_uint16),
+ ('DllCharacteristics', c_uint16),
+ ('SizeOfStackReserve', c_uint32),
+ ('SizeOfStackCommit' , c_uint32),
+ ('SizeOfHeapReserve', c_uint32),
+ ('SizeOfHeapCommit' , c_uint32),
+ ('LoaderFlags' , c_uint32),
+ ('NumberOfRvaAndSizes', c_uint32),
+ ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
+ ]
+
+class EFI_IMAGE_OPTIONAL_HEADER32_PLUS(Structure):
+ _fields_ = [
+ ('Magic', c_uint16),
+ ('MajorLinkerVersion', c_uint8),
+ ('MinorLinkerVersion', c_uint8),
+ ('SizeOfCode', c_uint32),
+ ('SizeOfInitializedData', c_uint32),
+ ('SizeOfUninitializedData', c_uint32),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('ImageBase', c_uint64),
+ ('SectionAlignment', c_uint32),
+ ('FileAlignment', c_uint32),
+ ('MajorOperatingSystemVersion', c_uint16),
+ ('MinorOperatingSystemVersion', c_uint16),
+ ('MajorImageVersion', c_uint16),
+ ('MinorImageVersion', c_uint16),
+ ('MajorSubsystemVersion', c_uint16),
+ ('MinorSubsystemVersion', c_uint16),
+ ('Win32VersionValue', c_uint32),
+ ('SizeOfImage', c_uint32),
+ ('SizeOfHeaders', c_uint32),
+ ('CheckSum' , c_uint32),
+ ('Subsystem', c_uint16),
+ ('DllCharacteristics', c_uint16),
+ ('SizeOfStackReserve', c_uint64),
+ ('SizeOfStackCommit' , c_uint64),
+ ('SizeOfHeapReserve', c_uint64),
+ ('SizeOfHeapCommit' , c_uint64),
+ ('LoaderFlags' , c_uint32),
+ ('NumberOfRvaAndSizes', c_uint32),
+ ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
+ ]
+
+class EFI_IMAGE_OPTIONAL_HEADER(Union):
+ _fields_ = [
+ ('PeOptHdr', EFI_IMAGE_OPTIONAL_HEADER32),
+ ('PePlusOptHdr', EFI_IMAGE_OPTIONAL_HEADER32_PLUS)
+ ]
+
+class EFI_IMAGE_NT_HEADERS32(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('FileHeader', EFI_IMAGE_FILE_HEADER),
+ ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER)
+ ]
+
+
+class EFI_IMAGE_DIRECTORY_ENTRY:
+ EXPORT = 0
+ IMPORT = 1
+ RESOURCE = 2
+ EXCEPTION = 3
+ SECURITY = 4
+ BASERELOC = 5
+ DEBUG = 6
+ COPYRIGHT = 7
+ GLOBALPTR = 8
+ TLS = 9
+ LOAD_CONFIG = 10
+
+class EFI_FV_FILETYPE:
+ ALL = 0x00
+ RAW = 0x01
+ FREEFORM = 0x02
+ SECURITY_CORE = 0x03
+ PEI_CORE = 0x04
+ DXE_CORE = 0x05
+ PEIM = 0x06
+ DRIVER = 0x07
+ COMBINED_PEIM_DRIVER = 0x08
+ APPLICATION = 0x09
+ SMM = 0x0a
+ FIRMWARE_VOLUME_IMAGE = 0x0b
+ COMBINED_SMM_DXE = 0x0c
+ SMM_CORE = 0x0d
+ OEM_MIN = 0xc0
+ OEM_MAX = 0xdf
+ DEBUG_MIN = 0xe0
+ DEBUG_MAX = 0xef
+ FFS_MIN = 0xf0
+ FFS_MAX = 0xff
+ FFS_PAD = 0xf0
+
+class EFI_SECTION_TYPE:
+ """Enumeration of all valid firmware file section types."""
+ ALL = 0x00
+ COMPRESSION = 0x01
+ GUID_DEFINED = 0x02
+ DISPOSABLE = 0x03
+ PE32 = 0x10
+ PIC = 0x11
+ TE = 0x12
+ DXE_DEPEX = 0x13
+ VERSION = 0x14
+ USER_INTERFACE = 0x15
+ COMPATIBILITY16 = 0x16
+ FIRMWARE_VOLUME_IMAGE = 0x17
+ FREEFORM_SUBTYPE_GUID = 0x18
+ RAW = 0x19
+ PEI_DEPEX = 0x1b
+ SMM_DEPEX = 0x1c
+
+def AlignPtr (offset, alignment = 8):
+ return (offset + alignment - 1) & ~(alignment - 1)
+
+def Bytes2Val (bytes):
+ return reduce(lambda x,y: (x<<8)|y, bytes[::-1] )
+
+def Val2Bytes (value, blen):
+ return [(value>>(i*8) & 0xff) for i in range(blen)]
+
+def OutputStruct (obj, indent = 0, plen = 0):
+ if indent:
+ body = ''
+ else:
+ body = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
+
+ if plen == 0:
+ plen = sizeof(obj)
+
+ max_key_len = 26
+ pstr = (' ' * (indent + 1) + '{0:<%d} = {1}\n') % max_key_len
+
+ for field in obj._fields_:
+ key = field[0]
+ val = getattr(obj, key)
+ rep = ''
+ if not isinstance(val, c_uint24) and isinstance(val, Structure):
+ body += pstr.format(key, val.__class__.__name__)
+ body += OutputStruct (val, indent + 1)
+ plen -= sizeof(val)
+ else:
+ if type(val) is str:
+ rep = "0x%X ('%s')" % (Bytes2Val(bytearray(val)), val)
+ elif type(val) in (int, long):
+ rep = '0x%X' % val
+ elif isinstance(val, c_uint24):
+ rep = '0x%X' % val.get_value()
+ elif 'c_ubyte_Array' in str(type(val)):
+ if sizeof(val) == 16:
+ rep = str(uuid.UUID(bytes = str(bytearray(val)))).upper()
+ else:
+ res = ['0x%02X'%i for i in bytearray(val)]
+ rep = '[%s]' % (','.join(res))
+ else:
+ rep = str(val)
+ plen -= sizeof(field[1])
+ body += pstr.format(key, rep)
+ if plen <= 0:
+ break
+ return body
+
+class Section:
+ def __init__(self, offset, secdata):
+ self.SecHdr = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
+ self.SecData = secdata[0:int(self.SecHdr.Size)]
+ self.Offset = offset
+
+class FirmwareFile:
+ def __init__(self, offset, filedata):
+ self.FfsHdr = EFI_FFS_FILE_HEADER.from_buffer (filedata, 0)
+ self.FfsData = filedata[0:int(self.FfsHdr.Size)]
+ self.Offset = offset
+ self.SecList = []
+
+ def ParseFfs(self):
+ ffssize = len(self.FfsData)
+ offset = sizeof(self.FfsHdr)
+ if self.FfsHdr.Name != '\xff' * 16:
+ while offset < ffssize:
+ sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
+ sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
+ self.SecList.append(sec)
+ offset += int(sechdr.Size)
+ offset = AlignPtr(offset, 4)
+
+class FirmwareVolume:
+ def __init__(self, offset, fvdata):
+ self.FvHdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (fvdata, 0)
+ self.FvData = fvdata[0 : self.FvHdr.FvLength]
+ self.Offset = offset
+ if self.FvHdr.ExtHeaderOffset > 0:
+ self.FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FvData, self.FvHdr.ExtHeaderOffset)
+ else:
+ self.FvExtHdr = None
+ self.FfsList = []
+
+ def ParseFv(self):
+ fvsize = len(self.FvData)
+ if self.FvExtHdr:
+ offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
+ else:
+ offset = self.FvHdr.HeaderLength
+ offset = AlignPtr(offset)
+ while offset < fvsize:
+ ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
+ if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
+ offset = fvsize
+ else:
+ ffs = FirmwareFile (offset, self.FvData[offset:offset + int(ffshdr.Size)])
+ ffs.ParseFfs()
+ self.FfsList.append(ffs)
+ offset += int(ffshdr.Size)
+ offset = AlignPtr(offset)
+
+class FspImage:
+ def __init__(self, offset, fih, fihoff, patch):
+ self.Fih = fih
+ self.FihOffset = fihoff
+ self.Offset = offset
+ self.FvIdxList = []
+ self.Type = "XTMSXXXXOXXXXXXX"[(fih.ComponentAttribute >> 12) & 0x0F]
+ self.PatchList = patch
+ self.PatchList.append(fihoff + 0x1C)
+
+ def AppendFv(self, FvIdx):
+ self.FvIdxList.append(FvIdx)
+
+ def Patch(self, delta, fdbin):
+ count = 0
+ applied = 0
+ for idx, patch in enumerate(self.PatchList):
+ ptype = (patch>>24) & 0x0F
+ if ptype not in [0x00, 0x0F]:
+ raise Exception('ERROR: Invalid patch type %d !' % ptype)
+ if patch & 0x80000000:
+ patch = self.Fih.ImageSize - (0x1000000 - (patch & 0xFFFFFF))
+ else:
+ patch = patch & 0xFFFFFF
+ if (patch < self.Fih.ImageSize) and (patch + sizeof(c_uint32) <= self.Fih.ImageSize):
+ offset = patch + self.Offset
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
+ value += delta
+ fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
+ applied += 1
+ count += 1
+ # Don't count the FSP base address patch entry appended at the end
+ if count != 0:
+ count -= 1
+ applied -= 1
+ return (count, applied)
+
+class FirmwareDevice:
+ def __init__(self, offset, fdfile):
+ self.FvList = []
+ self.FspList = []
+ self.FdFile = fdfile
+ self.Offset = 0
+ hfsp = open (self.FdFile, 'rb')
+ self.FdData = bytearray(hfsp.read())
+ hfsp.close()
+
+ def ParseFd(self):
+ offset = 0
+ fdsize = len(self.FdData)
+ self.FvList = []
+ while offset < fdsize:
+ fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
+ if '_FVH' != fvh.Signature:
+ raise Exception("ERROR: Invalid FV header !")
+ fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
+ fv.ParseFv ()
+ self.FvList.append(fv)
+ offset += fv.FvHdr.FvLength
+
+ def CheckFsp (self):
+ if len(self.FspList) == 0:
+ return
+
+ fih = None
+ for fsp in self.FspList:
+ if fsp.Fih.HeaderRevision < 3:
+ raise Exception("ERROR: FSP 1.x is not supported by this tool !")
+ if not fih:
+ fih = fsp.Fih
+ else:
+ newfih = fsp.Fih
+ if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
+ raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
+
+ def ParseFsp(self):
+ flen = 0
+ for idx, fv in enumerate(self.FvList):
+ # Check if this FV contains FSP header
+ if flen == 0:
+ if len(fv.FfsList) == 0:
+ continue
+ ffs = fv.FfsList[0]
+ if len(ffs.SecList) == 0:
+ continue
+ sec = ffs.SecList[0]
+ if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
+ continue
+ fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
+ fspoffset = fv.Offset
+ offset = fspoffset + fihoffset
+ fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
+ if 'FSPH' != fih.Signature:
+ continue
+
+ offset += fih.HeaderLength
+ offset = AlignPtr(offset, 4)
+ plist = []
+ while True:
+ fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)
+ if 'FSPP' != fch.Signature:
+ offset += fch.HeaderLength
+ offset = AlignPtr(offset, 4)
+ else:
+ fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)
+ offset += sizeof(fspp)
+ pdata = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)
+ plist = list(pdata)
+ break
+
+ fsp = FspImage (fspoffset, fih, fihoffset, plist)
+ fsp.AppendFv (idx)
+ self.FspList.append(fsp)
+ flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength
+ else:
+ fsp.AppendFv (idx)
+ flen -= fv.FvHdr.FvLength
+ if flen < 0:
+ raise Exception("ERROR: Incorrect FV size in image !")
+ self.CheckFsp ()
+
+class PeTeImage:
+ def __init__(self, offset, data):
+ self.Offset = offset
+ tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
+ if tehdr.Signature == 'VZ': # TE image
+ self.TeHdr = tehdr
+ elif tehdr.Signature == 'MZ': # PE image
+ self.TeHdr = None
+ self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
+ self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
+ if self.PeHdr.Signature != 0x4550:
+ raise Exception("ERROR: Invalid PE32 header !")
+ if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
+ if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
+ raise Exception("ERROR: Unsupported PE32 image !")
+ if self.PeHdr.OptionalHeader.PeOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
+ raise Exception("ERROR: No relocation information available !")
+ elif self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
+ if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32_PLUS.DataDirectory.offset:
+ raise Exception("ERROR: Unsupported PE32+ image !")
+ if self.PeHdr.OptionalHeader.PePlusOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
+ raise Exception("ERROR: No relocation information available !")
+ else:
+ raise Exception("ERROR: Invalid PE32 optional header !")
+ self.Offset = offset
+ self.Data = data
+ self.RelocList = []
+
+ def IsTeImage(self):
+ return self.TeHdr is not None
+
+ def ParseReloc(self):
+ if self.IsTeImage():
+ rsize = self.TeHdr.DataDirectoryBaseReloc.Size
+ roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ else:
+ if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
+ rsize = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
+ roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
+ if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
+ rsize = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
+ roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
+
+ alignment = 4
+ offset = roffset
+ while offset < roffset + rsize:
+ offset = AlignPtr(offset, 4)
+ blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
+ offset += sizeof(blkhdr)
+ # Read relocation type,offset pairs
+ rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
+ rnum = rlen/sizeof(c_uint16)
+ rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
+ for each in rdata:
+ roff = each & 0xfff
+ rtype = each >> 12
+ if rtype == 0: # IMAGE_REL_BASED_ABSOLUTE:
+ continue
+ if ((rtype != 3) and (rtype != 10)): # IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64
+ raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
+ # Calculate the offset of the relocation
+ aoff = blkhdr.PageRVA + roff
+ if self.IsTeImage():
+ aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
+ self.RelocList.append((rtype, aoff))
+ offset += sizeof(rdata)
+
+ def Rebase(self, delta, fdbin):
+ count = 0
+ if delta == 0:
+ return count
+
+ for (rtype, roff) in self.RelocList:
+ if rtype == 3: # IMAGE_REL_BASED_HIGHLOW
+ offset = roff + self.Offset
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
+ value += delta
+ fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
+ count += 1
+ elif rtype == 10: # IMAGE_REL_BASED_DIR64
+ offset = roff + self.Offset
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint64)])
+ value += delta
+ fdbin[offset:offset+sizeof(c_uint64)] = Val2Bytes(value, sizeof(c_uint64))
+ count += 1
+ else:
+ raise Exception('ERROR: Unknown relocation type %d !' % rtype)
+
+ if self.IsTeImage():
+ offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
+ size = EFI_TE_IMAGE_HEADER.ImageBase.size
+ else:
+ offset = self.Offset + self.DosHdr.e_lfanew
+ offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
+ offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
+ size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
+
+ value = Bytes2Val(fdbin[offset:offset+size]) + delta
+ fdbin[offset:offset+size] = Val2Bytes(value, size)
+
+ return count
+
+def ShowFspInfo (fspfile):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ print ("\nFound the following %d Firmware Volumes in FSP binary:" % (len(fd.FvList)))
+ for idx, fv in enumerate(fd.FvList):
+ name = fv.FvExtHdr.FvName
+ if not name:
+ name = '\xff' * 16
+ else:
+ name = str(bytearray(name))
+ guid = uuid.UUID(bytes = name)
+ print ("FV%d:" % idx)
+ print (" GUID : %s" % str(guid).upper())
+ print (" Offset : 0x%08X" % fv.Offset)
+ print (" Length : 0x%08X" % fv.FvHdr.FvLength)
+ print ("\n")
+
+ for fsp in fd.FspList:
+ fvlist = map(lambda x : 'FV%d' % x, fsp.FvIdxList)
+ print ("FSP_%s contains %s" % (fsp.Type, ','.join(fvlist)))
+ print ("%s" % (OutputStruct(fsp.Fih, 0, fsp.Fih.HeaderLength)))
+
+def GenFspHdr (fspfile, outdir, hfile):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ if not hfile:
+ hfile = os.path.splitext(os.path.basename(fspfile))[0] + '.h'
+ fspname, ext = os.path.splitext(os.path.basename(hfile))
+ filename = os.path.join(outdir, fspname + ext)
+ hfsp = open(filename, 'w')
+ hfsp.write ('%s\n\n' % CopyRightHeaderFile)
+
+ firstfv = True
+ for fsp in fd.FspList:
+ fih = fsp.Fih
+ if firstfv:
+ hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
+ hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
+ firstfv = False
+ fv = fd.FvList[fsp.FvIdxList[0]]
+ hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp.Type, fih.ImageBase))
+ hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp.Type, fv.Offset))
+ hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp.Type, fih.ImageSize))
+
+ hfsp.close()
+
+def SplitFspBin (fspfile, outdir, nametemplate):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ for fsp in fd.FspList:
+ ftype = fsp.Type
+ if not nametemplate:
+ nametemplate = fspfile
+ fspname, ext = os.path.splitext(os.path.basename(nametemplate))
+ filename = os.path.join(outdir, fspname + '_' + fsp.Type + ext)
+ hfsp = open(filename, 'wb')
+ print ("Create FSP component file '%s'" % filename)
+ for fvidx in fsp.FvIdxList:
+ fv = fd.FvList[fvidx]
+ hfsp.write(fv.FvData)
+ hfsp.close()
+
+def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
+ fd = FirmwareDevice(0, FspBinary)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ numcomp = len(FspComponent)
+ baselist = FspBase
+ if numcomp != len(baselist):
+ print "ERROR: Required number of base does not match number of FSP component !"
+ return
+
+ newfspbin = fd.FdData[:]
+
+ for idx, fspcomp in enumerate(FspComponent):
+
+ found = False
+ for fsp in fd.FspList:
+ ftype = fsp.Type.lower()
+ if ftype == fspcomp:
+ found = True
+ break
+
+ if not found:
+ print "ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper()
+ return
+
+ fspbase = baselist[idx]
+ if fspbase.startswith('0x'):
+ newbase = int(fspbase, 16)
+ else:
+ newbase = int(fspbase)
+ oldbase = fsp.Fih.ImageBase
+ delta = newbase - oldbase
+ print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
+
+ imglist = []
+ for fvidx in fsp.FvIdxList:
+ fv = fd.FvList[fvidx]
+ for ffs in fv.FfsList:
+ for sec in ffs.SecList:
+ if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32
+ offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
+ imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
+
+ fcount = 0
+ pcount = 0
+ for (offset, length) in imglist:
+ img = PeTeImage(offset, fd.FdData[offset:offset + length])
+ img.ParseReloc()
+ pcount += img.Rebase(delta, newfspbin)
+ fcount += 1
+
+ print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
+
+ (count, applied) = fsp.Patch(delta, newfspbin)
+ print " Patched %d entries using FSP patch table." % applied
+ if count != applied:
+ print " %d invalid entries are ignored !" % (count - applied)
+
+ if OutputFile == '':
+ filename = os.path.basename(FspBinary)
+ base, ext = os.path.splitext(filename)
+ OutputFile = base + "_%08X" % newbase + ext
+
+ fspname, ext = os.path.splitext(os.path.basename(OutputFile))
+ filename = os.path.join(OutputDir, fspname + ext)
+ fd = open(filename, "wb")
+ fd.write(newfspbin)
+ fd.close()
+
+def main ():
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(title='commands')
+
+ parser_rebase = subparsers.add_parser('rebase', help='rebase a FSP into a new base address')
+ parser_rebase.set_defaults(which='rebase')
+ parser_rebase.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_rebase.add_argument('-c', '--fspcomp', choices=['t','m','s','o'], nargs='+', dest='FspComponent', type=str, help='FSP component to rebase', default = "['t']", required = True)
+ parser_rebase.add_argument('-b', '--newbase', dest='FspBase', nargs='+', type=str, help='Rebased FSP binary file name', default = '', required = True)
+ parser_rebase.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_rebase.add_argument('-n', '--outfile', dest='OutputFile', type=str, help='Rebased FSP binary file name', default = '')
+
+ parser_split = subparsers.add_parser('split', help='split a FSP into multiple components')
+ parser_split.set_defaults(which='split')
+ parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
+
+ parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
+ parser_genhdr.set_defaults(which='genhdr')
+ parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '')
+
+ parser_info = subparsers.add_parser('info', help='display FSP information')
+ parser_info.set_defaults(which='info')
+ parser_info.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+
+ args = parser.parse_args()
+ if args.which in ['rebase', 'split', 'genhdr', 'info']:
+ if not os.path.exists(args.FspBinary):
+ raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
+ if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
+ raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
+
+ if args.which == 'rebase':
+ RebaseFspBin (args.FspBinary, args.FspComponent, args.FspBase, args.OutputDir, args.OutputFile)
+ elif args.which == 'split':
+ SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate)
+ elif args.which == 'genhdr':
+ GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
+ elif args.which == 'info':
+ ShowFspInfo (args.FspBinary)
+ else:
+ pass
+
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
--
2.19.0.397.gdd90340f6a-goog
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
next prev parent reply other threads:[~2018-09-18 15:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-18 13:32 [PATCH 1/3] IntelFsp2Pkg: Allow calling SplitFspBin.py directly Patrick Georgi
2018-09-18 13:32 ` [PATCH 2/3] IntelFsp2Pkg: Fix typo in SplitFspBin Patrick Georgi
2018-09-18 15:04 ` Desimone, Nathaniel L
2018-09-20 23:28 ` Chiu, Chasel
2018-09-26 3:11 ` Yao, Jiewen
2018-09-18 13:32 ` [PATCH 3/3] IntelFsp2Pkg: Tell git to format SplitFspBin.py with native newlines Patrick Georgi
2018-09-18 15:10 ` Desimone, Nathaniel L [this message]
2018-09-18 15:53 ` Patrick Georgi
2018-09-20 4:37 ` Desimone, Nathaniel L
2018-09-26 3:12 ` Yao, Jiewen
2018-09-26 15:58 ` Patrick Georgi
2018-09-27 0:40 ` Yao, Jiewen
2018-09-18 15:03 ` [PATCH 1/3] IntelFsp2Pkg: Allow calling SplitFspBin.py directly Desimone, Nathaniel L
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5608C728-C8C9-4D20-8C4D-FEC4FA974BA6@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox