Update SplitFspBin.py to latest from edk2

Updated to 9e639c1c
This commit is contained in:
Nate DeSimone 2019-10-28 17:13:33 -07:00
parent 7222054e9b
commit 0bc2b07eab
1 changed files with 74 additions and 39 deletions

View File

@ -1,13 +1,7 @@
## @ 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.
# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@ -18,14 +12,15 @@ import copy
import struct
import argparse
from ctypes import *
from functools import reduce
"""
This utility supports some operations for Intel FSP 2.0 image.
This utility supports some operations for Intel FSP 1.x/2.x 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
- Display FSP 1.x/2.x information header
- Split FSP 2.x image into individual FSP-T/M/S/O component
- Rebase FSP 1.x/2.x components to a different base address
- Generate FSP 1.x/2.x mapping C header file
"""
CopyRightHeaderFile = """/*
@ -346,6 +341,31 @@ def Bytes2Val (bytes):
def Val2Bytes (value, blen):
return [(value>>(i*8) & 0xff) for i in range(blen)]
def IsIntegerType (val):
if sys.version_info[0] < 3:
if type(val) in (int, long):
return True
else:
if type(val) is int:
return True
return False
def IsStrType (val):
if sys.version_info[0] < 3:
if type(val) is str:
return True
else:
if type(val) is bytes:
return True
return False
def HandleNameStr (val):
if sys.version_info[0] < 3:
rep = "0x%X ('%s')" % (Bytes2Val (bytearray (val)), val)
else:
rep = "0x%X ('%s')" % (Bytes2Val (bytearray (val)), str (val, 'utf-8'))
return rep
def OutputStruct (obj, indent = 0, plen = 0):
if indent:
body = ''
@ -367,15 +387,19 @@ def OutputStruct (obj, indent = 0, plen = 0):
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):
if IsStrType (val):
rep = HandleNameStr (val)
elif IsIntegerType (val):
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()
if sys.version_info[0] < 3:
rep = str(bytearray(val))
else:
rep = bytes(val)
rep = str(uuid.UUID(bytes_le = rep)).upper()
else:
res = ['0x%02X'%i for i in bytearray(val)]
rep = '[%s]' % (','.join(res))
@ -404,7 +428,7 @@ class FirmwareFile:
ffssize = len(self.FfsData)
offset = sizeof(self.FfsHdr)
if self.FfsHdr.Name != '\xff' * 16:
while offset < ffssize:
while offset < (ffssize - sizeof (EFI_COMMON_SECTION_HEADER)):
sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
self.SecList.append(sec)
@ -429,7 +453,7 @@ class FirmwareVolume:
else:
offset = self.FvHdr.HeaderLength
offset = AlignPtr(offset)
while offset < fvsize:
while offset < (fvsize - sizeof (EFI_FFS_FILE_HEADER)):
ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
offset = fvsize
@ -491,9 +515,9 @@ class FirmwareDevice:
offset = 0
fdsize = len(self.FdData)
self.FvList = []
while offset < fdsize:
while offset < (fdsize - sizeof (EFI_FIRMWARE_VOLUME_HEADER)):
fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
if '_FVH' != fvh.Signature:
if b'_FVH' != fvh.Signature:
raise Exception("ERROR: Invalid FV header !")
fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
fv.ParseFv ()
@ -506,8 +530,6 @@ class FirmwareDevice:
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:
@ -532,7 +554,7 @@ class FirmwareDevice:
fspoffset = fv.Offset
offset = fspoffset + fihoffset
fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
if 'FSPH' != fih.Signature:
if b'FSPH' != fih.Signature:
continue
offset += fih.HeaderLength
@ -540,7 +562,7 @@ class FirmwareDevice:
plist = []
while True:
fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)
if 'FSPP' != fch.Signature:
if b'FSPP' != fch.Signature:
offset += fch.HeaderLength
offset = AlignPtr(offset, 4)
else:
@ -565,9 +587,9 @@ 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
if tehdr.Signature == b'VZ': # TE image
self.TeHdr = tehdr
elif tehdr.Signature == 'MZ': # PE image
elif tehdr.Signature == b'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)
@ -612,7 +634,7 @@ class PeTeImage:
offset += sizeof(blkhdr)
# Read relocation type,offset pairs
rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
rnum = rlen/sizeof(c_uint16)
rnum = int (rlen/sizeof(c_uint16))
rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
for each in rdata:
roff = each & 0xfff
@ -674,8 +696,11 @@ def ShowFspInfo (fspfile):
if not name:
name = '\xff' * 16
else:
name = str(bytearray(name))
guid = uuid.UUID(bytes = name)
if sys.version_info[0] < 3:
name = str(bytearray(name))
else:
name = bytes(name)
guid = uuid.UUID(bytes_le = name)
print ("FV%d:" % idx)
print (" GUID : %s" % str(guid).upper())
print (" Offset : 0x%08X" % fv.Offset)
@ -703,7 +728,10 @@ def GenFspHdr (fspfile, outdir, hfile):
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))
if sys.version_info[0] < 3:
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
else:
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), str (fih.ImageId, 'utf-8')))
hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
firstfv = False
fv = fd.FvList[fsp.FvIdxList[0]]
@ -719,6 +747,8 @@ def SplitFspBin (fspfile, outdir, nametemplate):
fd.ParseFsp ()
for fsp in fd.FspList:
if fsp.Fih.HeaderRevision < 3:
raise Exception("ERROR: FSP 1.x is not supported by the split command !")
ftype = fsp.Type
if not nametemplate:
nametemplate = fspfile
@ -739,7 +769,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
numcomp = len(FspComponent)
baselist = FspBase
if numcomp != len(baselist):
print "ERROR: Required number of base does not match number of FSP component !"
print ("ERROR: Required number of base does not match number of FSP component !")
return
newfspbin = fd.FdData[:]
@ -748,13 +778,18 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
found = False
for fsp in fd.FspList:
# Is this FSP 1.x single binary?
if fsp.Fih.HeaderRevision < 3:
found = True
ftype = 'X'
break
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()
print ("ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper())
return
fspbase = baselist[idx]
@ -764,7 +799,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
newbase = int(fspbase)
oldbase = fsp.Fih.ImageBase
delta = newbase - oldbase
print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
print ("Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase))
imglist = []
for fvidx in fsp.FvIdxList:
@ -783,12 +818,12 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
pcount += img.Rebase(delta, newfspbin)
fcount += 1
print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
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
print (" Patched %d entries using FSP patch table." % applied)
if count != applied:
print " %d invalid entries are ignored !" % (count - applied)
print (" %d invalid entries are ignored !" % (count - applied))
if OutputFile == '':
filename = os.path.basename(FspBinary)
@ -803,7 +838,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
def main ():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title='commands')
subparsers = parser.add_subparsers(title='commands', dest="which")
parser_rebase = subparsers.add_parser('rebase', help='rebase a FSP into a new base address')
parser_rebase.set_defaults(which='rebase')
@ -845,7 +880,7 @@ def main ():
elif args.which == 'info':
ShowFspInfo (args.FspBinary)
else:
pass
parser.print_help()
return 0