tools: Extend pldm_fwup_pkg_creator
Extend the pldm_fwup_pkg_creator script to handle multiple record
descriptors in the firmware device ID record. The metadata json also
handles vendor defined descriptors.
Tested: Verified this change by using the updated json in the patch
and sample images to create a package. The fields of the package
header were verified for accuracy.
Signed-off-by: Tom Joseph <rushtotom@gmail.com>
Change-Id: I9efde5689e551170b46a4e6ee4ea1e5624173420
diff --git a/tools/fw-update/pldm_fwup_pkg_creator.py b/tools/fw-update/pldm_fwup_pkg_creator.py
index 1273296..5d603b8 100755
--- a/tools/fw-update/pldm_fwup_pkg_creator.py
+++ b/tools/fw-update/pldm_fwup_pkg_creator.py
@@ -22,13 +22,26 @@
("UTF16LE", 4),
("UTF16BE", 5)])
-descriptor_type_name_length = {
+initial_descriptor_type_name_length = {
0x0000: ["PCI Vendor ID", 2],
0x0001: ["IANA Enterprise ID", 4],
0x0002: ["UUID", 16],
0x0003: ["PnP Vendor ID", 3],
0x0004: ["ACPI Vendor ID", 4]}
+descriptor_type_name_length = {
+ 0x0000: ["PCI Vendor ID", 2],
+ 0x0001: ["IANA Enterprise ID", 4],
+ 0x0002: ["UUID", 16],
+ 0x0003: ["PnP Vendor ID", 3],
+ 0x0004: ["ACPI Vendor ID", 4],
+ 0x0100: ["PCI Device ID", 2],
+ 0x0101: ["PCI Subsystem Vendor ID", 2],
+ 0x0102: ["PCI Subsystem ID", 2],
+ 0x0103: ["PCI Revision ID", 1],
+ 0x0104: ["PnP Product Identifier", 4],
+ 0x0105: ["ACPI Product Identifier", 4]}
+
def check_string_length(string):
"""Check if the length of the string is not greater than 255."""
@@ -185,6 +198,74 @@
return applicable_components
+def prepare_record_descriptors(descriptors):
+ '''
+ This function processes the Descriptors and prepares the RecordDescriptors
+ section of the the firmware device ID record.
+
+ Parameters:
+ descriptors: Descriptors entry
+
+ Returns:
+ RecordDescriptors, DescriptorCount
+ '''
+ record_descriptors = bytearray()
+ vendor_defined_desc_type = 65535
+ vendor_desc_title_str_type_len = 1
+ vendor_desc_title_str_len_len = 1
+ descriptor_count = 0
+
+ for descriptor in descriptors:
+
+ descriptor_type = descriptor["DescriptorType"]
+ if descriptor_count == 0:
+ if initial_descriptor_type_name_length.get(descriptor_type) \
+ is None:
+ sys.exit("ERROR: Initial descriptor type not supported")
+ else:
+ if descriptor_type_name_length.get(descriptor_type) is None and \
+ descriptor_type != vendor_defined_desc_type:
+ sys.exit("ERROR: Descriptor type not supported")
+
+ if descriptor_type == vendor_defined_desc_type:
+ vendor_desc_title_str = \
+ descriptor["VendorDefinedDescriptorTitleString"]
+ vendor_desc_data = descriptor["VendorDefinedDescriptorData"]
+ check_string_length(vendor_desc_title_str)
+ vendor_desc_title_str_type = string_types["ASCII"]
+ descriptor_length = vendor_desc_title_str_type_len + \
+ vendor_desc_title_str_len_len + len(vendor_desc_title_str) + \
+ len(bytearray.fromhex(vendor_desc_data))
+ format_string = '<HHBB' + str(len(vendor_desc_title_str)) + 's'
+ record_descriptors.extend(struct.pack(
+ format_string,
+ descriptor_type,
+ descriptor_length,
+ vendor_desc_title_str_type,
+ len(vendor_desc_title_str),
+ vendor_desc_title_str.encode('ascii')))
+ record_descriptors.extend(bytearray.fromhex(vendor_desc_data))
+ descriptor_count += 1
+ else:
+ descriptor_type = descriptor["DescriptorType"]
+ descriptor_data = descriptor["DescriptorData"]
+ descriptor_length = len(bytearray.fromhex(descriptor_data))
+ if descriptor_length != \
+ descriptor_type_name_length.get(descriptor_type)[1]:
+ err_string = "ERROR: Descriptor type - " + \
+ descriptor_type_name_length.get(descriptor_type)[0] + \
+ " length is incorrect"
+ sys.exit(err_string)
+ format_string = '<HH'
+ record_descriptors.extend(struct.pack(
+ format_string,
+ descriptor_type,
+ descriptor_length))
+ record_descriptors.extend(bytearray.fromhex(descriptor_data))
+ descriptor_count += 1
+ return record_descriptors, descriptor_count
+
+
def write_fw_device_identification_area(pldm_fw_up_pkg, metadata,
component_bitmap_bit_length):
'''
@@ -193,7 +274,7 @@
This function writes the DeviceIDRecordCount and the
FirmwareDeviceIDRecords into the firmware update package by processing the
metadata JSON. Currently there is no support for optional
- FirmwareDevicePackageData and for Additional descriptors.
+ FirmwareDevicePackageData.
Parameters:
pldm_fw_up_pkg: PLDM FW update package
@@ -216,8 +297,7 @@
# RecordLength size
record_length = 2
- # Only initial descriptor type supported now
- descriptor_count = 1
+ # DescriptorCount
record_length += 1
# DeviceUpdateOptionFlags
@@ -257,32 +337,15 @@
round(len(applicable_components)/8)
record_length += applicable_components_bitfield_length
- initial_descriptor = device["InitialDescriptor"]
- initial_descriptor_type = initial_descriptor["InitialDescriptorType"]
- initial_descriptor_data = initial_descriptor["InitialDescriptorData"]
-
- # InitialDescriptorType
- if descriptor_type_name_length.get(initial_descriptor_type) is None:
- sys.exit("ERROR: Initial descriptor type not supported")
- record_length += 2
-
- # InitialDescriptorLength
- initial_descriptor_length = \
- len(bytearray.fromhex(initial_descriptor_data))
- if initial_descriptor_length != \
- descriptor_type_name_length.get(initial_descriptor_type)[1]:
- err_string = "ERROR: Initial descriptor type - " + \
- descriptor_type_name_length.get(initial_descriptor_type)[0] + \
- " length is incorrect"
- sys.exit(err_string)
- record_length += 2
-
- # InitialDescriptorData, the byte order in the JSON is retained.
- record_length += initial_descriptor_length
+ # RecordDescriptors
+ descriptors = device["Descriptors"]
+ record_descriptors, descriptor_count = \
+ prepare_record_descriptors(descriptors)
+ record_length += len(record_descriptors)
format_string = '<HBIBBH' + \
str(applicable_components_bitfield_length) + 's' + \
- str(len(component_image_set_version_string)) + 'sHH'
+ str(len(component_image_set_version_string)) + 's'
pldm_fw_up_pkg.write(
struct.pack(
format_string,
@@ -293,10 +356,8 @@
len(component_image_set_version_string),
fw_device_pkg_data_length,
applicable_components.tobytes(),
- component_image_set_version_string.encode('ascii'),
- initial_descriptor_type,
- initial_descriptor_length))
- pldm_fw_up_pkg.write(bytearray.fromhex(initial_descriptor_data))
+ component_image_set_version_string.encode('ascii')))
+ pldm_fw_up_pkg.write(record_descriptors)
def write_component_image_info_area(pldm_fw_up_pkg, metadata, image_files):