## @file
# Generating Firmware Medata Data version 1 based on sepcification:
# Platform Security Firmware Update for A-profile 1.0:
# https://developer.arm.com/documentation/den0118/latest
#
# Copyright (c) 2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# @par Reference(s):
# - Platform Security Firmware Update for the A-profile Specification 1.0
# (https://developer.arm.com/documentation/den0118/latest)
#
# @par Glossary:
# - FW - Firmware
# - FWU - Firmware Update
# - PSA - Platform Security update for the A-profile specification
# - IMG - Image
# - MM - Management Mode
# - PROP - Property
# - Bkup, Bkp - Backup
#
import os
import sys
import argparse
import glob
import shutil
import struct
import uuid
import binascii
import zlib
#
# Global for help information
#
__prog__ = 'GenFwuMetadata.py'
__version__ = '0.1'
__description__ = 'Generate Firwmare update Metadata.\n'
class FwuImageBankInfoV2:
#
# struct fwu_image_bank_info_v2 {
# uuid_t img_guid;
# uint32_t accepted;
# uint8_t reserved_4[4];
# }
#
_StructFormat = "<16sII"
_StructSize = struct.calcsize(_StructFormat)
def __init__(self, ImageGuid=None):
self.ImageGuid = ImageGuid
self.Accepted = 1
self.Reserved4 = 0x00000000
def Encode(self):
FwuImageBankInfo = struct.pack(
FwuImageBankInfoV2._StructFormat,
self.ImageGuid.bytes_le,
self.Accepted,
self.Reserved4)
return FwuImageBankInfo
def Decode(self, Buffer):
if len(Buffer) != FwuImageBankInfoV2._StructSize:
raise ValueError
(ImageGuid, Accepted, Reserved4) = \
struct.unpack(
FwuImageBankInfoV2._StructFormat,
Buffer[0:FwuImageBankInfoV2._StructSize])
if Reserved4 != 0x00000000:
raise ValueError
self.ImageGuid = uuid.UUID(bytes_le=ImageGuid)
self.Accepted = Accepted
def Dump(self):
print("\t\t\timg_guid: {Guid}".format(Guid=str(self.ImageGuid)))
print("\t\t\taccept: {Accpeted:d}".format(Accpeted=self.Accepted))
print("\t\t\treserved_4: 0x{Reserved:08x}".format(Reserved=self.Reserved4))
class FwuImageEntryV2:
#
# struct fwu_image_entry_v2 {
# uuid_t img_type_guid;
# uuid_t location_guid;
# struct fwu_image_bank_info_v2 img_bank_info[];
# }
#
_StructFormat = "<16s16s"
_StructSize = struct.calcsize(_StructFormat)
def __init__(self, ImageTypeGuid=None, LocationGuid=None, ImageBankInfoBuffer='b'):
self.ImageTypeGuid = ImageTypeGuid
self.LocationGuid = LocationGuid
self.FwuImageBankInfo = ImageBankInfoBuffer
def Encode(self):
FwuImageEntry = struct.pack(
FwuImageEntryV2._StructFormat,
self.ImageTypeGuid.bytes_le,
self.LocationGuid.bytes_le)
return FwuImageEntry + self.FwuImageBankInfo
def Decode(self, Buffer, NumBanks):
EntrySize = FwuImageEntryV2._StructSize + (FwuImageBankInfoV2._StructSize * NumBanks)
if len(Buffer) != EntrySize:
raise ValueError
(ImageTypeGuid, LocationGuid) = \
struct.unpack(
FwuImageEntryV2._StructFormat,
Buffer[0:FwuImageEntryV2._StructSize])
self.ImageTypeGuid = uuid.UUID(bytes_le=ImageTypeGuid)
self.LocationGuid = uuid.UUID(bytes_le=LocationGuid)
self.FwuImageBankInfo = Buffer[FwuImageEntryV2._StructSize:EntrySize]
def Dump(self, NumBanks):
print("\t\timg_type_guid: {Guid}".format(Guid=str(self.ImageTypeGuid)))
print("\t\tlocation_guid: {Guid}".format(Guid=str(self.LocationGuid)))
for Index in range(NumBanks):
print("\t\tBank[{bank:d}]:".format(bank=Index))
FwuImageBankInfo = FwuImageBankInfoV2()
FwuImageBankInfo.Decode(
self.FwuImageBankInfo[
Index * FwuImageBankInfoV2._StructSize:
(Index + 1) * FwuImageBankInfoV2._StructSize
])
FwuImageBankInfo.Dump()
class FwuFwStoreDescV2:
#
# struct fwu_fw_store_desc_v2 {
# uint8_t num_banks;
# uint8_t reserved;
# uint16_t num_images;
# uint16_t img_entry_size;
# uint16_t bank_info_entry_size;
# struct fwu_image_entry_v2 img_entry[];
# }
#
_StructFormat = "