Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Copyright (C) 2018-2019, Intel Corporation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #ifndef _PLDMFW_PRIVATE_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #define _PLDMFW_PRIVATE_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) /* The following data structures define the layout of a firmware binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * following the "PLDM For Firmware Update Specification", DMTF standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * #DSP0267.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * pldmfw.c uses these structures to implement a simple engine that will parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * a fw binary file in this format and perform a firmware update for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Due to the variable sized data layout, alignment of fields within these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * structures is not guaranteed when reading. For this reason, all multi-byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * field accesses should be done using the unaligned access macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Additionally, the standard specifies that multi-byte fields are in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * LittleEndian format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * The structure definitions are not made public, in order to keep direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * accesses within code that is prepared to deal with the limitation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * unaligned access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* UUID for PLDM firmware packages: f018878c-cb7d-4943-9800-a02f059aca02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static const uuid_t pldm_firmware_header_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	UUID_INIT(0xf018878c, 0xcb7d, 0x4943,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		  0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* Revision number of the PLDM header format this code supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define PACKAGE_HEADER_FORMAT_REVISION 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* timestamp104 structure defined in PLDM Base specification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define PLDM_TIMESTAMP_SIZE 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct __pldm_timestamp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	u8 b[PLDM_TIMESTAMP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) } __packed __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* Package Header Information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) struct __pldm_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	uuid_t id;			    /* PackageHeaderIdentifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	u8 revision;			    /* PackageHeaderFormatRevision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	__le16 size;			    /* PackageHeaderSize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct __pldm_timestamp release_date; /* PackageReleaseDateTime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	__le16 component_bitmap_len;	    /* ComponentBitmapBitLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	u8 version_type;		    /* PackageVersionStringType */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	u8 version_len;			    /* PackageVersionStringLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 * DSP0267 also includes the following variable length fields at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	 * end of this structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	 * PackageVersionString, length is version_len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	 * The total size of this section is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 *   sizeof(pldm_header) + version_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	u8 version_string[];		/* PackageVersionString */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) } __packed __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) /* Firmware Device ID Record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) struct __pldmfw_record_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	__le16 record_len;		/* RecordLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	u8 descriptor_count;		/* DescriptorCount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	__le32 device_update_flags;	/* DeviceUpdateOptionFlags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	u8 version_type;		/* ComponentImageSetVersionType */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	u8 version_len;			/* ComponentImageSetVersionLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	__le16 package_data_len;	/* FirmwareDevicePackageDataLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 * DSP0267 also includes the following variable length fields at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	 * end of this structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 * ApplicableComponents, length is component_bitmap_len from header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 * ComponentImageSetVersionString, length is version_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 * RecordDescriptors, a series of TLVs with 16bit type and length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * FirmwareDevicePackageData, length is package_data_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * The total size of each record is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 *   sizeof(pldmfw_record_info) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 *   component_bitmap_len (converted to bytes!) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 *   version_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 *   <length of RecordDescriptors> +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 *   package_data_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u8 variable_record_data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) } __packed __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) /* Firmware Descriptor Definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) struct __pldmfw_desc_tlv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	__le16 type;			/* DescriptorType */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	__le16 size;			/* DescriptorSize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	u8 data[];			/* DescriptorData */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) } __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /* Firmware Device Identification Area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) struct __pldmfw_record_area {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	u8 record_count;		/* DeviceIDRecordCount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/* This is not a struct type because the size of each record varies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	u8 records[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Individual Component Image Information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct __pldmfw_component_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	__le16 classification;		/* ComponentClassfication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	__le16 identifier;		/* ComponentIdentifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	__le32 comparison_stamp;	/* ComponentComparisonStamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	__le16 options;			/* componentOptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	__le16 activation_method;	/* RequestedComponentActivationMethod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	__le32 location_offset;		/* ComponentLocationOffset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	__le32 size;			/* ComponentSize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	u8 version_type;		/* ComponentVersionStringType */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	u8 version_len;		/* ComponentVersionStringLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 * DSP0267 also includes the following variable length fields at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * end of this structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * ComponentVersionString, length is version_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * The total size of this section is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 *   sizeof(pldmfw_component_info) + version_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	u8 version_string[];		/* ComponentVersionString */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) } __packed __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Component Image Information Area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct __pldmfw_component_area {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	__le16 component_image_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* This is not a struct type because the component size varies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	u8 components[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } __aligned(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * pldm_first_desc_tlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * @start: byte offset of the start of the descriptor TLVs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * Converts the starting offset of the descriptor TLVs into a pointer to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * first descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define pldm_first_desc_tlv(start)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	((const struct __pldmfw_desc_tlv *)(start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * pldm_next_desc_tlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * @desc: pointer to a descriptor TLV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * Finds the pointer to the next descriptor following a given descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define pldm_next_desc_tlv(desc)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	((const struct __pldmfw_desc_tlv *)((desc)->data +			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 					     get_unaligned_le16(&(desc)->size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * pldm_for_each_desc_tlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * @i: variable to store descriptor index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * @desc: variable to store descriptor pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * @start: byte offset of the start of the descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * @count: the number of descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * for loop macro to iterate over all of the descriptors of a given PLDM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define pldm_for_each_desc_tlv(i, desc, start, count)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	for ((i) = 0, (desc) = pldm_first_desc_tlv(start);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	     (i) < (count);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	     (i)++, (desc) = pldm_next_desc_tlv(desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * pldm_first_record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * @start: byte offset of the start of the PLDM records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * Converts a starting offset of the PLDM records into a pointer to the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define pldm_first_record(start)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	((const struct __pldmfw_record_info *)(start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * pldm_next_record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * @record: pointer to a PLDM record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * Finds a pointer to the next record following a given record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define pldm_next_record(record)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	((const struct __pldmfw_record_info *)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	 ((const u8 *)(record) + get_unaligned_le16(&(record)->record_len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * pldm_for_each_record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * @i: variable to store record index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * @record: variable to store record pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * @start: byte offset of the start of the records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * @count: the number of records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * for loop macro to iterate over all of the records of a PLDM file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define pldm_for_each_record(i, record, start, count)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	for ((i) = 0, (record) = pldm_first_record(start);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	     (i) < (count);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	     (i)++, (record) = pldm_next_record(record))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * pldm_first_component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * @start: byte offset of the start of the PLDM components
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * Convert a starting offset of the PLDM components into a pointer to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * first component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define pldm_first_component(start)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	((const struct __pldmfw_component_info *)(start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * pldm_next_component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * @component: pointer to a PLDM component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * Finds a pointer to the next component following a given component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define pldm_next_component(component)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	((const struct __pldmfw_component_info *)((component)->version_string +	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 						  (component)->version_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * pldm_for_each_component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * @i: variable to store component index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * @component: variable to store component pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * @start: byte offset to the start of the first component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * @count: the number of components
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * for loop macro to iterate over all of the components of a PLDM file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define pldm_for_each_component(i, component, start, count)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	for ((i) = 0, (component) = pldm_first_component(start);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	     (i) < (count);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	     (i)++, (component) = pldm_next_component(component))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif