/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2019, Intel Corporation. */
#ifndef _PLDMFW_PRIVATE_H_
#define _PLDMFW_PRIVATE_H_
/* The following data structures define the layout of a firmware binary
* following the " PLDM For Firmware Update Specification " , DMTF standard
* # DSP0267 .
*
* pldmfw . c uses these structures to implement a simple engine that will parse
* a fw binary file in this format and perform a firmware update for a given
* device .
*
* Due to the variable sized data layout , alignment of fields within these
* structures is not guaranteed when reading . For this reason , all multi - byte
* field accesses should be done using the unaligned access macros .
* Additionally , the standard specifies that multi - byte fields are in
* LittleEndian format .
*
* The structure definitions are not made public , in order to keep direct
* accesses within code that is prepared to deal with the limitation of
* unaligned access .
*/
/* UUID for PLDM firmware packages: f018878c-cb7d-4943-9800-a02f059aca02 */
static const uuid_t pldm_firmware_header_id =
UUID_INIT(0 xf018878c, 0 xcb7d, 0 x4943,
0 x98, 0 x00, 0 xa0, 0 x2f, 0 x05, 0 x9a, 0 xca, 0 x02);
/* Revision number of the PLDM header format this code supports */
#define PACKAGE_HEADER_FORMAT_REVISION 0 x01
/* timestamp104 structure defined in PLDM Base specification */
#define PLDM_TIMESTAMP_SIZE 13
struct __pldm_timestamp {
u8 b[PLDM_TIMESTAMP_SIZE];
} __packed __aligned(1 );
/* Package Header Information */
struct __pldm_header {
uuid_t id; /* PackageHeaderIdentifier */
u8 revision; /* PackageHeaderFormatRevision */
__le16 size; /* PackageHeaderSize */
struct __pldm_timestamp release_date; /* PackageReleaseDateTime */
__le16 component_bitmap_len; /* ComponentBitmapBitLength */
u8 version_type; /* PackageVersionStringType */
u8 version_len; /* PackageVersionStringLength */
/*
* DSP0267 also includes the following variable length fields at the
* end of this structure :
*
* PackageVersionString , length is version_len .
*
* The total size of this section is
* sizeof ( pldm_header ) + version_len ;
*/
u8 version_string[]; /* PackageVersionString */
} __packed __aligned(1 );
/* Firmware Device ID Record */
struct __pldmfw_record_info {
__le16 record_len; /* RecordLength */
u8 descriptor_count; /* DescriptorCount */
__le32 device_update_flags; /* DeviceUpdateOptionFlags */
u8 version_type; /* ComponentImageSetVersionType */
u8 version_len; /* ComponentImageSetVersionLength */
__le16 package_data_len; /* FirmwareDevicePackageDataLength */
/*
* DSP0267 also includes the following variable length fields at the
* end of this structure :
*
* ApplicableComponents , length is component_bitmap_len from header
* ComponentImageSetVersionString , length is version_len
* RecordDescriptors , a series of TLVs with 16 bit type and length
* FirmwareDevicePackageData , length is package_data_len
*
* The total size of each record is
* sizeof ( pldmfw_record_info ) +
* component_bitmap_len ( converted to bytes ! ) +
* version_len +
* < length of RecordDescriptors > +
* package_data_len
*/
u8 variable_record_data[];
} __packed __aligned(1 );
/* Firmware Descriptor Definition */
struct __pldmfw_desc_tlv {
__le16 type; /* DescriptorType */
__le16 size; /* DescriptorSize */
u8 data[]; /* DescriptorData */
} __aligned(1 );
/* Firmware Device Identification Area */
struct __pldmfw_record_area {
u8 record_count; /* DeviceIDRecordCount */
/* This is not a struct type because the size of each record varies */
u8 records[];
} __aligned(1 );
/* Individual Component Image Information */
struct __pldmfw_component_info {
__le16 classification; /* ComponentClassfication */
__le16 identifier; /* ComponentIdentifier */
__le32 comparison_stamp; /* ComponentComparisonStamp */
__le16 options; /* componentOptions */
__le16 activation_method; /* RequestedComponentActivationMethod */
__le32 location_offset; /* ComponentLocationOffset */
__le32 size; /* ComponentSize */
u8 version_type; /* ComponentVersionStringType */
u8 version_len; /* ComponentVersionStringLength */
/*
* DSP0267 also includes the following variable length fields at the
* end of this structure :
*
* ComponentVersionString , length is version_len
*
* The total size of this section is
* sizeof ( pldmfw_component_info ) + version_len ;
*/
u8 version_string[]; /* ComponentVersionString */
} __packed __aligned(1 );
/* Component Image Information Area */
struct __pldmfw_component_area {
__le16 component_image_count;
/* This is not a struct type because the component size varies */
u8 components[];
} __aligned(1 );
/**
* pldm_first_desc_tlv
* @ start : byte offset of the start of the descriptor TLVs
*
* Converts the starting offset of the descriptor TLVs into a pointer to the
* first descriptor .
*/
#define pldm_first_desc_tlv(start) \
((const struct __pldmfw_desc_tlv *)(start))
/**
* pldm_next_desc_tlv
* @ desc : pointer to a descriptor TLV
*
* Finds the pointer to the next descriptor following a given descriptor
*/
#define pldm_next_desc_tlv(desc) \
((const struct __pldmfw_desc_tlv *)((desc)->data + \
get_unaligned_le16(&(desc)->size)))
/**
* pldm_for_each_desc_tlv
* @ i : variable to store descriptor index
* @ desc : variable to store descriptor pointer
* @ start : byte offset of the start of the descriptors
* @ count : the number of descriptors
*
* for loop macro to iterate over all of the descriptors of a given PLDM
* record .
*/
#define pldm_for_each_desc_tlv(i, desc, start, count) \
for ((i) = 0 , (desc) = pldm_first_desc_tlv(start); \
(i) < (count); \
(i)++, (desc) = pldm_next_desc_tlv(desc))
/**
* pldm_first_record
* @ start : byte offset of the start of the PLDM records
*
* Converts a starting offset of the PLDM records into a pointer to the first
* record .
*/
#define pldm_first_record(start) \
((const struct __pldmfw_record_info *)(start))
/**
* pldm_next_record
* @ record : pointer to a PLDM record
*
* Finds a pointer to the next record following a given record
*/
#define pldm_next_record(record) \
((const struct __pldmfw_record_info *) \
((const u8 *)(record) + get_unaligned_le16(&(record)->record_len)))
/**
* pldm_for_each_record
* @ i : variable to store record index
* @ record : variable to store record pointer
* @ start : byte offset of the start of the records
* @ count : the number of records
*
* for loop macro to iterate over all of the records of a PLDM file .
*/
#define pldm_for_each_record(i, record, start, count) \
for ((i) = 0 , (record) = pldm_first_record(start); \
(i) < (count); \
(i)++, (record) = pldm_next_record(record))
/**
* pldm_first_component
* @ start : byte offset of the start of the PLDM components
*
* Convert a starting offset of the PLDM components into a pointer to the
* first component
*/
#define pldm_first_component(start) \
((const struct __pldmfw_component_info *)(start))
/**
* pldm_next_component
* @ component : pointer to a PLDM component
*
* Finds a pointer to the next component following a given component
*/
#define pldm_next_component(component) \
((const struct __pldmfw_component_info *)((component)->version_string + \
(component)->version_len))
/**
* pldm_for_each_component
* @ i : variable to store component index
* @ component : variable to store component pointer
* @ start : byte offset to the start of the first component
* @ count : the number of components
*
* for loop macro to iterate over all of the components of a PLDM file .
*/
#define pldm_for_each_component(i, component, start, count) \
for ((i) = 0 , (component) = pldm_first_component(start); \
(i) < (count); \
(i)++, (component) = pldm_next_component(component))
#endif
Messung V0.5 in Prozent C=79 H=77 G=77
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland