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 { 1366c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->record_handle); 1466c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->version); 1566c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->type); 1666c7723aSAndrew Jeffery pldm_msgbuf_extract(ctx, hdr->record_change_num); 1766c7723aSAndrew 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: 3666c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u8); 377992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: 3866c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_s8); 397992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: 4066c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u16); 417992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: 4266c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_s16); 437992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: 4466c7723aSAndrew Jeffery return pldm_msgbuf_extract(ctx, dst->value_u32); 457992eb84SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: 4666c7723aSAndrew 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, 6066c7723aSAndrew Jeffery void *val) 61840b140aSAndrew Jeffery { 62840b140aSAndrew Jeffery switch (tag) { 63840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: 6466c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8(ctx, val); 65840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: 6666c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8(ctx, val); 67840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: 6866c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16(ctx, val); 69840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: 7066c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16(ctx, val); 71840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: 7266c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32(ctx, val); 73840b140aSAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: 7466c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32(ctx, val); 75840b140aSAndrew Jeffery } 76840b140aSAndrew Jeffery 77840b140aSAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 78840b140aSAndrew Jeffery } 79840b140aSAndrew Jeffery 8066c7723aSAndrew Jeffery #define pldm_msgbuf_extract_range_field_format(ctx, tag, dst) \ 8166c7723aSAndrew Jeffery pldm_msgbuf_extract_typecheck(union_range_field_format, \ 8266c7723aSAndrew Jeffery pldm__msgbuf_extract_range_field_format, \ 8366c7723aSAndrew Jeffery dst, ctx, tag, (void *)&(dst)) 847992eb84SAndrew Jeffery __attribute__((always_inline)) static inline int 8566c7723aSAndrew Jeffery pldm__msgbuf_extract_range_field_format(struct pldm_msgbuf *ctx, 867992eb84SAndrew Jeffery enum pldm_range_field_format tag, 8766c7723aSAndrew Jeffery void *rff) 887992eb84SAndrew Jeffery { 897992eb84SAndrew Jeffery switch (tag) { 907992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT8: 9166c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8( 9266c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 9366c7723aSAndrew Jeffery value_u8)); 947992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT8: 9566c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8( 9666c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 9766c7723aSAndrew Jeffery value_s8)); 987992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT16: 9966c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16( 10066c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 10166c7723aSAndrew Jeffery value_u16)); 1027992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT16: 10366c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16( 10466c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 10566c7723aSAndrew Jeffery value_s16)); 1067992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_UINT32: 10766c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32( 10866c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 10966c7723aSAndrew Jeffery value_u32)); 1107992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_SINT32: 11166c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32( 11266c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 11366c7723aSAndrew Jeffery value_s32)); 1147992eb84SAndrew Jeffery case PLDM_RANGE_FIELD_FORMAT_REAL32: 11566c7723aSAndrew Jeffery return pldm__msgbuf_extract_real32( 11666c7723aSAndrew Jeffery ctx, ((char *)rff) + offsetof(union_range_field_format, 11766c7723aSAndrew 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, 12666c7723aSAndrew Jeffery enum pldm_effecter_data_size tag, void *dst) 1273884c44dSAndrew Jeffery { 1283884c44dSAndrew Jeffery switch (tag) { 1293884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT8: 13066c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint8(ctx, dst); 1313884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT8: 13266c7723aSAndrew Jeffery return pldm__msgbuf_extract_int8(ctx, dst); 1333884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT16: 13466c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint16(ctx, dst); 1353884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT16: 13666c7723aSAndrew Jeffery return pldm__msgbuf_extract_int16(ctx, dst); 1373884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_UINT32: 13866c7723aSAndrew Jeffery return pldm__msgbuf_extract_uint32(ctx, dst); 1393884c44dSAndrew Jeffery case PLDM_EFFECTER_DATA_SIZE_SINT32: 14066c7723aSAndrew Jeffery return pldm__msgbuf_extract_int32(ctx, dst); 1413884c44dSAndrew Jeffery } 1423884c44dSAndrew Jeffery 1433884c44dSAndrew Jeffery return -PLDM_ERROR_INVALID_DATA; 1443884c44dSAndrew Jeffery } 1453884c44dSAndrew Jeffery 146*d4878cdfSThu Nguyen #define pldm_msgbuf_extract_effecter_data(ctx, tag, dst) \ 147*d4878cdfSThu Nguyen pldm_msgbuf_extract_typecheck(union_effecter_data_size, \ 148*d4878cdfSThu Nguyen pldm__msgbuf_extract_range_field_format, \ 149*d4878cdfSThu Nguyen dst, ctx, tag, (void *)&(dst)) 150*d4878cdfSThu Nguyen __attribute__((always_inline)) static inline int 151*d4878cdfSThu Nguyen pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf *ctx, 152*d4878cdfSThu Nguyen enum pldm_effecter_data_size tag, void *ed) 153*d4878cdfSThu Nguyen { 154*d4878cdfSThu Nguyen switch (tag) { 155*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_UINT8: 156*d4878cdfSThu Nguyen return pldm__msgbuf_extract_uint8( 157*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 158*d4878cdfSThu Nguyen value_u8)); 159*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_SINT8: 160*d4878cdfSThu Nguyen return pldm__msgbuf_extract_int8( 161*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 162*d4878cdfSThu Nguyen value_s8)); 163*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_UINT16: 164*d4878cdfSThu Nguyen return pldm__msgbuf_extract_uint16( 165*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 166*d4878cdfSThu Nguyen value_u16)); 167*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_SINT16: 168*d4878cdfSThu Nguyen return pldm__msgbuf_extract_int16( 169*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 170*d4878cdfSThu Nguyen value_s16)); 171*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_UINT32: 172*d4878cdfSThu Nguyen return pldm__msgbuf_extract_uint32( 173*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 174*d4878cdfSThu Nguyen value_u32)); 175*d4878cdfSThu Nguyen case PLDM_EFFECTER_DATA_SIZE_SINT32: 176*d4878cdfSThu Nguyen return pldm__msgbuf_extract_int32( 177*d4878cdfSThu Nguyen ctx, ((char *)ed) + offsetof(union_effecter_data_size, 178*d4878cdfSThu Nguyen value_s32)); 179*d4878cdfSThu Nguyen } 180*d4878cdfSThu Nguyen 181*d4878cdfSThu Nguyen return -PLDM_ERROR_INVALID_DATA; 182*d4878cdfSThu Nguyen } 183*d4878cdfSThu Nguyen 18466c7723aSAndrew Jeffery #ifdef __cplusplus 18566c7723aSAndrew Jeffery #include <type_traits> 18666c7723aSAndrew Jeffery 18766c7723aSAndrew Jeffery template <typename T> 18866c7723aSAndrew Jeffery static inline int pldm_msgbuf_typecheck_range_field_format( 18966c7723aSAndrew Jeffery struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff) 19066c7723aSAndrew Jeffery { 19166c7723aSAndrew Jeffery static_assert(std::is_same<union_range_field_format, T>::value); 19266c7723aSAndrew Jeffery return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff); 19366c7723aSAndrew Jeffery } 19466c7723aSAndrew Jeffery #endif 19566c7723aSAndrew Jeffery 1967992eb84SAndrew Jeffery #endif 197