1691668feSPatrick Williams /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 27992eb84SAndrew Jeffery #ifndef PLDM_MSGBUF_PLATFORM_H 37992eb84SAndrew Jeffery #define PLDM_MSGBUF_PLATFORM_H 47992eb84SAndrew Jeffery 57992eb84SAndrew Jeffery #include "../msgbuf.h" 67992eb84SAndrew Jeffery #include <libpldm/base.h> 77992eb84SAndrew Jeffery #include <libpldm/platform.h> 87992eb84SAndrew Jeffery 97992eb84SAndrew Jeffery static inline int 107992eb84SAndrew Jeffery pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx, 117992eb84SAndrew Jeffery struct pldm_value_pdr_hdr *hdr) 127992eb84SAndrew Jeffery { 13*66c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->record_handle); 14*66c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->version); 15*66c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->type); 16*66c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->record_change_num); 17*66c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->length); 187992eb84SAndrew Jeffery 197992eb84SAndrew Jeffery return pldm_msgbuf_validate(ctx); 207992eb84SAndrew Jeffery } 217992eb84SAndrew Jeffery 227992eb84SAndrew Jeffery /* 237992eb84SAndrew Jeffery * We use __attribute__((always_inline)) below so the compiler has visibility of 247992eb84SAndrew Jeffery * the switch() at the call site. It is often the case that the size of multiple 257992eb84SAndrew Jeffery * fields depends on the tag. Inlining thus gives the compiler visibility to 267992eb84SAndrew Jeffery * hoist one tag-based code-path condition to cover all invocations. 277992eb84SAndrew Jeffery */ 287992eb84SAndrew Jeffery 297992eb84SAndrew Jeffery __attribute__((always_inline)) static inline int 307992eb84SAndrew Jeffery pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf *ctx, 317992eb84SAndrew Jeffery enum pldm_sensor_readings_data_type tag, 327992eb84SAndrew Jeffery union_sensor_data_size *dst) 337992eb84SAndrew Jeffery { 347992eb84SAndrew Jeffery switch (tag) { 357992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: 36*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u8); 377992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: 38*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_s8); 397992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: 40*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u16); 417992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: 42*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_s16); 437992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: 44*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u32); 457992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: 46*66c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_s32); 477992eb84SAndrew Jeffery } 487992eb84SAndrew Jeffery 497992eb84SAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 507992eb84SAndrew Jeffery } 517992eb84SAndrew Jeffery 52840b140aSAndrew Jeffery /* 53840b140aSAndrew Jeffery * This API is bad, but it's because the caller's APIs are also bad. They should 54840b140aSAndrew Jeffery * have used the approach used by callers of pldm_msgbuf_extract_sensor_data() 55840b140aSAndrew Jeffery * above 56840b140aSAndrew Jeffery */ 57840b140aSAndrew Jeffery __attribute__((always_inline)) static inline int 58840b140aSAndrew Jeffery pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx, 59cd07fec7SThu Nguyen enum pldm_sensor_readings_data_type tag, 60*66c7723aSAndrew Jeffery void *val) 61840b140aSAndrew Jeffery { 62840b140aSAndrew Jeffery switch (tag) { 63840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: 64*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8(ctx, val); 65840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: 66*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8(ctx, val); 67840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: 68*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16(ctx, val); 69840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: 70*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16(ctx, val); 71840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: 72*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32(ctx, val); 73840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: 74*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32(ctx, val); 75840b140aSAndrew Jeffery } 76840b140aSAndrew Jeffery 77840b140aSAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 78840b140aSAndrew Jeffery } 79840b140aSAndrew Jeffery 80*66c7723aSAndrew Jeffery #define pldm_msgbuf_extract_range_field_format(ctx, tag, dst) \ 81*66c7723aSAndrew Jeffery pldm_msgbuf_extract_typecheck(union_range_field_format, \ 82*66c7723aSAndrew Jeffery pldm__msgbuf_extract_range_field_format, \ 83*66c7723aSAndrew Jeffery dst, ctx, tag, (void *)&(dst)) 847992eb84SAndrew Jeffery __attribute__((always_inline)) static inline int 85*66c7723aSAndrew Jeffery pldm__msgbuf_extract_range_field_format(struct pldm_msgbuf *ctx, 867992eb84SAndrew Jeffery enum pldm_range_field_format tag, 87*66c7723aSAndrew Jeffery void *rff) 887992eb84SAndrew Jeffery { 897992eb84SAndrew Jeffery switch (tag) { 907992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT8: 91*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8( 92*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 93*66c7723aSAndrew Jeffery value_u8)); 947992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT8: 95*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8( 96*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 97*66c7723aSAndrew Jeffery value_s8)); 987992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT16: 99*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16( 100*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 101*66c7723aSAndrew Jeffery value_u16)); 1027992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT16: 103*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16( 104*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 105*66c7723aSAndrew Jeffery value_s16)); 1067992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT32: 107*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32( 108*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 109*66c7723aSAndrew Jeffery value_u32)); 1107992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT32: 111*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32( 112*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 113*66c7723aSAndrew Jeffery value_s32)); 1147992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_REAL32: 115*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_real32( 116*66c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 117*66c7723aSAndrew Jeffery value_f32)); 1187992eb84SAndrew Jeffery } 1197992eb84SAndrew Jeffery 1207992eb84SAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 1217992eb84SAndrew Jeffery } 1227992eb84SAndrew Jeffery 1233884c44dSAndrew Jeffery /* This API is bad, but it's because the caller's APIs are also bad */ 1243884c44dSAndrew Jeffery __attribute__((always_inline)) static inline int 1253884c44dSAndrew Jeffery pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx, 126*66c7723aSAndrew Jeffery enum pldm_effecter_data_size tag, void *dst) 1273884c44dSAndrew Jeffery { 1283884c44dSAndrew Jeffery switch (tag) { 1293884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT8: 130*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8(ctx, dst); 1313884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT8: 132*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8(ctx, dst); 1333884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT16: 134*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16(ctx, dst); 1353884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT16: 136*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16(ctx, dst); 1373884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT32: 138*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32(ctx, dst); 1393884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT32: 140*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32(ctx, dst); 1413884c44dSAndrew Jeffery } 1423884c44dSAndrew Jeffery 1433884c44dSAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 1443884c44dSAndrew Jeffery } 1453884c44dSAndrew Jeffery 146*66c7723aSAndrew Jeffery #ifdef __cplusplus 147*66c7723aSAndrew Jeffery #include <type_traits> 148*66c7723aSAndrew Jeffery 149*66c7723aSAndrew Jeffery template <typename T> 150*66c7723aSAndrew Jeffery static inline int pldm_msgbuf_typecheck_range_field_format( 151*66c7723aSAndrew Jeffery struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff) 152*66c7723aSAndrew Jeffery { 153*66c7723aSAndrew Jeffery static_assert(std::is_same<union_range_field_format, T>::value); 154*66c7723aSAndrew Jeffery return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff); 155*66c7723aSAndrew Jeffery } 156*66c7723aSAndrew Jeffery #endif 157*66c7723aSAndrew Jeffery 1587992eb84SAndrew Jeffery #endif 159