IntelFsp2Pkg/Tools: Add FSP rebasing function into SplitFspBin tool
Enhanced the SplitFspBin tool in IntelFsp2Pkg to support: - Rebase FSP 2.0 components to a different base address - Display FSP 2.0 information header Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Maurice Ma <maurice.ma@intel.com> Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
This commit is contained in:
@@ -20,18 +20,26 @@ import argparse
|
|||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This utility supports some operations for Intel FSP image.
|
This utility supports some operations for Intel FSP 2.0 image.
|
||||||
It supports:
|
It supports:
|
||||||
- Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C
|
- Display FSP 2.0 information header
|
||||||
and generate the mapping header file.
|
- 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):
|
class c_uint24(Structure):
|
||||||
"""Little-Endian 24-bit Unsigned Integer"""
|
"""Little-Endian 24-bit Unsigned Integer"""
|
||||||
_pack_ = 1
|
_pack_ = 1
|
||||||
_fields_ = [
|
_fields_ = [('Data', (c_uint8 * 3))]
|
||||||
('Data', (c_uint8 * 3))
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, val=0):
|
def __init__(self, val=0):
|
||||||
self.set_value(val)
|
self.set_value(val)
|
||||||
@@ -39,26 +47,23 @@ class c_uint24(Structure):
|
|||||||
def __str__(self, indent=0):
|
def __str__(self, indent=0):
|
||||||
return '0x%.6x' % self.value
|
return '0x%.6x' % self.value
|
||||||
|
|
||||||
def get_value(self):
|
def __int__(self):
|
||||||
return (
|
return self.get_value()
|
||||||
(self.Data[0] ) +
|
|
||||||
(self.Data[1] << 8) +
|
|
||||||
(self.Data[2] << 16)
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_value(self, val):
|
def set_value(self, val):
|
||||||
self.Data[0] = (val ) & 0xff
|
self.Data[0:3] = Val2Bytes(val, 3)
|
||||||
self.Data[1] = (val >> 8) & 0xff
|
|
||||||
self.Data[2] = (val >> 16) & 0xff
|
def get_value(self):
|
||||||
|
return Bytes2Val(self.Data[0:3])
|
||||||
|
|
||||||
value = property(get_value, set_value)
|
value = property(get_value, set_value)
|
||||||
|
|
||||||
class EFI_FIRMWARE_VOLUME_HEADER(Structure):
|
class EFI_FIRMWARE_VOLUME_HEADER(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('ZeroVector', ARRAY(c_uint8, 16)),
|
('ZeroVector', ARRAY(c_uint8, 16)),
|
||||||
('FileSystemGuid', ARRAY(c_char, 16)),
|
('FileSystemGuid', ARRAY(c_uint8, 16)),
|
||||||
('FvLength', c_uint64),
|
('FvLength', c_uint64),
|
||||||
('Signature', c_uint32),
|
('Signature', ARRAY(c_char, 4)),
|
||||||
('Attributes', c_uint32),
|
('Attributes', c_uint32),
|
||||||
('HeaderLength', c_uint16),
|
('HeaderLength', c_uint16),
|
||||||
('Checksum', c_uint16),
|
('Checksum', c_uint16),
|
||||||
@@ -69,7 +74,7 @@ class EFI_FIRMWARE_VOLUME_HEADER(Structure):
|
|||||||
|
|
||||||
class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
|
class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('FvName', ARRAY(c_char, 16)),
|
('FvName', ARRAY(c_uint8, 16)),
|
||||||
('ExtHeaderSize', c_uint32)
|
('ExtHeaderSize', c_uint32)
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -81,7 +86,7 @@ class EFI_FFS_INTEGRITY_CHECK(Structure):
|
|||||||
|
|
||||||
class EFI_FFS_FILE_HEADER(Structure):
|
class EFI_FFS_FILE_HEADER(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('Name', ARRAY(c_char, 16)),
|
('Name', ARRAY(c_uint8, 16)),
|
||||||
('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
|
('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
|
||||||
('Type', c_uint8),
|
('Type', c_uint8),
|
||||||
('Attributes', c_uint8),
|
('Attributes', c_uint8),
|
||||||
@@ -95,268 +100,579 @@ class EFI_COMMON_SECTION_HEADER(Structure):
|
|||||||
('Type', c_uint8)
|
('Type', c_uint8)
|
||||||
]
|
]
|
||||||
|
|
||||||
class FSP_INFORMATION_HEADER(Structure):
|
class FSP_COMMON_HEADER(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('Signature', c_uint32),
|
('Signature', ARRAY(c_char, 4)),
|
||||||
('HeaderLength', c_uint32),
|
('HeaderLength', c_uint32)
|
||||||
('Reserved1', ARRAY(c_uint8, 3)),
|
|
||||||
('HeaderRevision', c_uint8),
|
|
||||||
('ImageRevision', c_uint32),
|
|
||||||
('ImageId', c_uint64),
|
|
||||||
('ImageSize', c_uint32),
|
|
||||||
('ImageBase', c_uint32),
|
|
||||||
('ImageAttribute', c_uint32),
|
|
||||||
('CfgRegionOffset', c_uint32),
|
|
||||||
('CfgRegionSize', c_uint32),
|
|
||||||
('ApiEntryNum', c_uint32),
|
|
||||||
('NemInitEntry', c_uint32),
|
|
||||||
('FspInitEntry', c_uint32),
|
|
||||||
('NotifyPhaseEntry', c_uint32),
|
|
||||||
('FspMemoryInitEntry', c_uint32),
|
|
||||||
('TempRamExitEntry', c_uint32),
|
|
||||||
('FspSiliconInitEntry', c_uint32)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class FspFv:
|
class FSP_INFORMATION_HEADER(Structure):
|
||||||
HeaderFile = """/*
|
_fields_ = [
|
||||||
*
|
('Signature', ARRAY(c_char, 4)),
|
||||||
* Automatically generated file; DO NOT EDIT.
|
('HeaderLength', c_uint32),
|
||||||
* FSP mapping file
|
('Reserved1', c_uint16),
|
||||||
*
|
('SpecVersion', c_uint8),
|
||||||
*/
|
('HeaderRevision', c_uint8),
|
||||||
"""
|
('ImageRevision', c_uint32),
|
||||||
FspNameDict = {
|
('ImageId', ARRAY(c_char, 8)),
|
||||||
"0" : "-C.Fv",
|
('ImageSize', c_uint32),
|
||||||
"1" : "-T.Fv",
|
('ImageBase', c_uint32),
|
||||||
"2" : "-M.Fv",
|
('ImageAttribute', c_uint16),
|
||||||
"3" : "-S.Fv",
|
('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)
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, FvBin):
|
class FSP_PATCH_TABLE(Structure):
|
||||||
self.FspFv = {}
|
_fields_ = [
|
||||||
self.FvList = []
|
('Signature', ARRAY(c_char, 4)),
|
||||||
self.FspBin = FvBin
|
('HeaderLength', c_uint16),
|
||||||
hfsp = open (self.FspBin, 'r+b')
|
('HeaderRevision', c_uint8),
|
||||||
self.FspDat = bytearray(hfsp.read())
|
('Reserved', c_uint8),
|
||||||
hfsp.close()
|
('PatchEntryNum', c_uint32)
|
||||||
|
]
|
||||||
|
|
||||||
def OutputStruct (self, obj, indent = 0):
|
class EFI_IMAGE_DATA_DIRECTORY(Structure):
|
||||||
max_key_len = 20
|
_fields_ = [
|
||||||
pstr = (' ' * indent + '{0:<%d} = {1}\n') % max_key_len
|
('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 PE_RELOC_BLOCK_HEADER(Structure):
|
||||||
|
_fields_ = [
|
||||||
|
('PageRVA', c_uint32),
|
||||||
|
('BlockSize', c_uint32)
|
||||||
|
]
|
||||||
|
|
||||||
|
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:
|
if indent:
|
||||||
s = ''
|
body = ''
|
||||||
else:
|
else:
|
||||||
s = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
|
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_:
|
for field in obj._fields_:
|
||||||
key = field[0]
|
key = field[0]
|
||||||
val = getattr(obj, key)
|
val = getattr(obj, key)
|
||||||
rep = ''
|
rep = ''
|
||||||
|
|
||||||
if not isinstance(val, c_uint24) and isinstance(val, Structure):
|
if not isinstance(val, c_uint24) and isinstance(val, Structure):
|
||||||
s += pstr.format(key, val.__class__.__name__)
|
body += pstr.format(key, val.__class__.__name__)
|
||||||
s += self.OutputStruct (val, indent + 1)
|
body += OutputStruct (val, indent + 1)
|
||||||
|
plen -= sizeof(val)
|
||||||
else:
|
else:
|
||||||
if type(val) in (int, long):
|
if type(val) is str:
|
||||||
rep = hex(val)
|
rep = "0x%X ('%s')" % (Bytes2Val(bytearray(val)), val)
|
||||||
elif isinstance(val, str) and (len(val) == 16):
|
elif type(val) in (int, long):
|
||||||
rep = str(uuid.UUID(bytes = val))
|
rep = '0x%X' % val
|
||||||
elif isinstance(val, c_uint24):
|
elif isinstance(val, c_uint24):
|
||||||
rep = hex(val.get_value())
|
rep = '0x%X' % val.get_value()
|
||||||
elif 'c_ubyte_Array' in str(type(val)):
|
elif 'c_ubyte_Array' in str(type(val)):
|
||||||
rep = str(list(bytearray(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:
|
else:
|
||||||
rep = str(val)
|
rep = str(val)
|
||||||
s += pstr.format(key, rep)
|
plen -= sizeof(field[1])
|
||||||
return s
|
body += pstr.format(key, rep)
|
||||||
|
if plen <= 0:
|
||||||
|
break
|
||||||
|
return body
|
||||||
|
|
||||||
def PrintFv (self):
|
class Section:
|
||||||
print ("FV LIST:")
|
def __init__(self, offset, secdata):
|
||||||
idx = 0
|
self.SecHdr = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
|
||||||
for (fvh, fvhe, offset) in self.FvList:
|
self.SecData = secdata[0:int(self.SecHdr.Size)]
|
||||||
guid = uuid.UUID(bytes = fvhe.FvName)
|
self.Offset = offset
|
||||||
print ("FV%d FV GUID:%s Offset:0x%08X Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength))
|
|
||||||
idx = idx + 1
|
|
||||||
print ("\nFSP LIST:")
|
|
||||||
for fsp in self.FspFv:
|
|
||||||
print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1]))
|
|
||||||
print "\nFSP%s Info Header:" % fsp
|
|
||||||
fih = self.FspFv[fsp][0]
|
|
||||||
|
|
||||||
def AlaignPtr (self, offset, alignment = 8):
|
class FirmwareFile:
|
||||||
return (offset + alignment - 1) & ~(alignment - 1)
|
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 GetFspInfoHdr (self, fvh, fvhe, fvoffset):
|
def ParseFfs(self):
|
||||||
if fvhe:
|
ffssize = len(self.FfsData)
|
||||||
offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize
|
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:
|
else:
|
||||||
offset = fvh.HeaderLength
|
self.FvExtHdr = None
|
||||||
offset = self.AlaignPtr(offset)
|
self.FfsList = []
|
||||||
|
|
||||||
# Now it should be 1st FFS
|
def ParseFv(self):
|
||||||
ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset)
|
fvsize = len(self.FvData)
|
||||||
offset += sizeof(ffs)
|
if self.FvExtHdr:
|
||||||
offset = self.AlaignPtr(offset)
|
offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
|
||||||
|
|
||||||
# Now it should be 1st Section
|
|
||||||
sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset)
|
|
||||||
offset += sizeof(sec)
|
|
||||||
|
|
||||||
# Now it should be FSP_INFO_HEADER
|
|
||||||
offset += fvoffset
|
|
||||||
fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset)
|
|
||||||
if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return fih
|
|
||||||
|
|
||||||
def GetFvHdr (self, offset):
|
|
||||||
fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset)
|
|
||||||
if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]:
|
|
||||||
return None, None
|
|
||||||
if fvh.ExtHeaderOffset > 0:
|
|
||||||
offset += fvh.ExtHeaderOffset
|
|
||||||
fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset)
|
|
||||||
else:
|
else:
|
||||||
fvhe = None
|
offset = self.FvHdr.HeaderLength
|
||||||
return fvh, fvhe
|
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)
|
||||||
|
|
||||||
def GetFvData(self, idx):
|
class FspImage:
|
||||||
(fvh, fvhe, offset) = self.FvList[idx]
|
def __init__(self, offset, fih, fihoff, patch):
|
||||||
return self.FspDat[offset:offset+fvh.FvLength]
|
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):
|
def CheckFsp (self):
|
||||||
if len(self.FspFv) == 0:
|
if len(self.FspList) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
fih = None
|
fih = None
|
||||||
for fv in self.FspFv:
|
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:
|
if not fih:
|
||||||
fih = self.FspFv[fv][0]
|
fih = fsp.Fih
|
||||||
else:
|
else:
|
||||||
newfih = self.FspFv[fv][0]
|
newfih = fsp.Fih
|
||||||
if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
|
if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
|
||||||
raise Exception("Inconsistent FSP ImageId or ImageRevision detected !")
|
raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
|
||||||
return
|
|
||||||
|
|
||||||
def WriteFsp(self, dir, name):
|
|
||||||
if not name:
|
|
||||||
name = self.FspBin
|
|
||||||
fspname, ext = os.path.splitext(os.path.basename(name))
|
|
||||||
for fv in self.FspFv:
|
|
||||||
filename = os.path.join(dir, fspname + fv + ext)
|
|
||||||
hfsp = open(filename, 'w+b')
|
|
||||||
for fvidx in self.FspFv[fv][1]:
|
|
||||||
hfsp.write (self.GetFvData(fvidx))
|
|
||||||
hfsp.close()
|
|
||||||
|
|
||||||
def WriteMap(self, dir, hfile):
|
|
||||||
if not hfile:
|
|
||||||
hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h'
|
|
||||||
fspname, ext = os.path.splitext(os.path.basename(hfile))
|
|
||||||
filename = os.path.join(dir, fspname + ext)
|
|
||||||
hfsp = open(filename, 'w')
|
|
||||||
hfsp.write ('%s\n\n' % self.HeaderFile)
|
|
||||||
|
|
||||||
firstfv = True
|
|
||||||
for fsp in self.FspFv:
|
|
||||||
fih = self.FspFv[fsp][0]
|
|
||||||
fvs = self.FspFv[fsp][1]
|
|
||||||
if firstfv:
|
|
||||||
IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1])
|
|
||||||
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (fih.ImageId, IdStr))
|
|
||||||
hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
|
|
||||||
firstfv = False
|
|
||||||
hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp, fih.ImageBase))
|
|
||||||
hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp, self.FvList[fvs[0]][-1]))
|
|
||||||
hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp, fih.ImageSize))
|
|
||||||
hfsp.close()
|
|
||||||
|
|
||||||
def ParseFsp(self):
|
def ParseFsp(self):
|
||||||
self.FspFv = {}
|
|
||||||
flen = 0
|
flen = 0
|
||||||
for (fvh, fvhe, offset) in self.FvList:
|
for idx, fv in enumerate(self.FvList):
|
||||||
fih = self.GetFspInfoHdr (fvh, fvhe, offset)
|
# Check if this FV contains FSP header
|
||||||
if fih:
|
if flen == 0:
|
||||||
if flen != 0:
|
if len(fv.FfsList) == 0:
|
||||||
raise Exception("Incorrect FV size in image !")
|
continue
|
||||||
ftype = str((fih.ImageAttribute >> 28) & 0xF)
|
ffs = fv.FfsList[0]
|
||||||
if ftype not in self.FspNameDict:
|
if len(ffs.SecList) == 0:
|
||||||
raise Exception("Unknown Attribute in image !")
|
continue
|
||||||
fname = self.FspNameDict[str(ftype)]
|
sec = ffs.SecList[0]
|
||||||
if fname in self.FspFv:
|
if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
|
||||||
raise Exception("Multiple '%s' in image !" % fname)
|
continue
|
||||||
self.FspFv[fname] = (copy.deepcopy(fih), [])
|
fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
|
||||||
flen = fih.ImageSize
|
fspoffset = fv.Offset
|
||||||
if flen > 0:
|
offset = fspoffset + fihoffset
|
||||||
flen = flen - fvh.FvLength
|
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:
|
if flen < 0:
|
||||||
raise Exception("Incorrect FV size in image !")
|
raise Exception("ERROR: Incorrect FV size in image !")
|
||||||
self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset)))
|
self.CheckFsp ()
|
||||||
|
|
||||||
def AddFv(self, offset):
|
class TeImage:
|
||||||
fvh, fvhe = self.GetFvHdr (offset)
|
def __init__(self, offset, tedata):
|
||||||
if fvh is None:
|
self.Offset = offset
|
||||||
raise Exception('FV signature is not valid !')
|
self.TeHdr = EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0)
|
||||||
fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset)
|
self.TeData = tedata
|
||||||
self.FvList.append(fvitem)
|
self.RelocList = []
|
||||||
return fvh.FvLength
|
|
||||||
|
|
||||||
def ParseFv(self):
|
def ParseReloc(self):
|
||||||
offset = 0
|
rsize = self.TeHdr.DataDirectoryBaseReloc.Size
|
||||||
while (offset < len(self.FspDat)):
|
roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
|
||||||
fv_len = self.AddFv (offset)
|
alignment = 4
|
||||||
offset += fv_len
|
offset = roffset
|
||||||
|
while offset < roffset + rsize:
|
||||||
|
offset = AlignPtr(offset, 4)
|
||||||
|
blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData, 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.TeData, offset)
|
||||||
|
for each in rdata:
|
||||||
|
roff = each & 0xfff
|
||||||
|
rtype = each >> 12
|
||||||
|
if rtype == 0: # IMAGE_REL_BASED.ABSOLUTE:
|
||||||
|
continue
|
||||||
|
if rtype != 3: # IMAGE_REL_BASED_HIGHLOW
|
||||||
|
raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
|
||||||
|
# Calculate the offset of the relocation
|
||||||
|
aoff = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + blkhdr.PageRVA + roff
|
||||||
|
self.RelocList.append((rtype, aoff))
|
||||||
|
offset += sizeof(rdata)
|
||||||
|
|
||||||
def GenFspHdr (fspfile, outdir, hfile, show):
|
def Rebase(self, delta, fdbin):
|
||||||
fsp_fv = FspFv(fspfile)
|
count = 0
|
||||||
fsp_fv.ParseFv()
|
if delta == 0:
|
||||||
fsp_fv.ParseFsp()
|
return count
|
||||||
fsp_fv.CheckFsp()
|
|
||||||
if show:
|
|
||||||
fsp_fv.PrintFv()
|
|
||||||
fsp_fv.WriteMap(outdir, hfile)
|
|
||||||
|
|
||||||
def SplitFspBin (fspfile, outdir, nametemplate, show):
|
for (rtype, roff) in self.RelocList:
|
||||||
fsp_fv = FspFv(fspfile)
|
if rtype == 0x03: # HIGHLOW
|
||||||
fsp_fv.ParseFv()
|
offset = roff + self.Offset
|
||||||
fsp_fv.ParseFsp()
|
value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
|
||||||
if show:
|
value += delta
|
||||||
fsp_fv.PrintFv()
|
fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
|
||||||
fsp_fv.WriteFsp(outdir, nametemplate)
|
count += 1
|
||||||
|
else:
|
||||||
|
raise Exception('ERROR: Unknown relocation type %d !' % rtype)
|
||||||
|
|
||||||
|
tehdr = self.TeHdr
|
||||||
|
tehdr.ImageBase += delta
|
||||||
|
offset = self.Offset
|
||||||
|
fdbin[offset:offset+sizeof(tehdr)] = bytearray(tehdr)
|
||||||
|
|
||||||
|
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 ("Ceate 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)
|
||||||
|
|
||||||
|
telist = []
|
||||||
|
for fvidx in fsp.FvIdxList:
|
||||||
|
fv = fd.FvList[fvidx]
|
||||||
|
for ffs in fv.FfsList:
|
||||||
|
for sec in ffs.SecList:
|
||||||
|
if sec.SecHdr.Type == EFI_SECTION_TYPE.TE: # TE
|
||||||
|
offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
|
||||||
|
telist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
|
||||||
|
elif sec.SecHdr.Type == EFI_SECTION_TYPE.PE32: # PE
|
||||||
|
raise Exception("ERROR: PE32 Section is not supported !")
|
||||||
|
|
||||||
|
fcount = 0
|
||||||
|
tecount = 0
|
||||||
|
for (teoffset, telen) in telist:
|
||||||
|
tehdr = EFI_TE_IMAGE_HEADER.from_buffer (fd.FdData, teoffset)
|
||||||
|
if 'VZ' != tehdr.Signature:
|
||||||
|
raise Exception("ERROR: Invalid TE header !")
|
||||||
|
te = TeImage(teoffset, fd.FdData[teoffset:teoffset + telen])
|
||||||
|
te.ParseReloc()
|
||||||
|
tecount += te.Rebase(delta, newfspbin)
|
||||||
|
fcount += 1
|
||||||
|
print " Patched %d entries in %d TE images." % (tecount, 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 ():
|
def main ():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
subparsers = parser.add_subparsers(title='commands')
|
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 = subparsers.add_parser('split', help='split a FSP into multiple components')
|
||||||
parser_split.set_defaults(which='split')
|
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('-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('-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_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
|
||||||
parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
|
|
||||||
|
|
||||||
parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
|
parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
|
||||||
parser_genhdr.set_defaults(which='genhdr')
|
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('-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('-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_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '')
|
||||||
parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
|
|
||||||
|
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()
|
args = parser.parse_args()
|
||||||
if args.which in ['split', 'genhdr']:
|
if args.which in ['rebase', 'split', 'genhdr', 'info']:
|
||||||
if not os.path.exists(args.FspBinary):
|
if not os.path.exists(args.FspBinary):
|
||||||
raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary)
|
raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
|
||||||
if not os.path.exists(args.OutputDir):
|
if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
|
||||||
raise Exception ("Invalid output directory '%s' !" % args.OutputDir)
|
raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
|
||||||
|
|
||||||
if args.which == 'split':
|
if args.which == 'rebase':
|
||||||
SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p)
|
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':
|
elif args.which == 'genhdr':
|
||||||
GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName, args.p)
|
GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
|
||||||
|
elif args.which == 'info':
|
||||||
|
ShowFspInfo (args.FspBinary)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print 'Done!'
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Reference in New Issue
Block a user