xref: /openbmc/libpldm/src/msgbuf/platform.h (revision cd07fec7)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #ifndef PLDM_MSGBUF_PLATFORM_H
3 #define PLDM_MSGBUF_PLATFORM_H
4 
5 #include "../msgbuf.h"
6 #include <libpldm/base.h>
7 #include <libpldm/platform.h>
8 
9 static inline int
10 pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx,
11 				  struct pldm_value_pdr_hdr *hdr)
12 {
13 	pldm_msgbuf_extract(ctx, &hdr->record_handle);
14 	pldm_msgbuf_extract(ctx, &hdr->version);
15 	pldm_msgbuf_extract(ctx, &hdr->type);
16 	pldm_msgbuf_extract(ctx, &hdr->record_change_num);
17 	pldm_msgbuf_extract(ctx, &hdr->length);
18 
19 	return pldm_msgbuf_validate(ctx);
20 }
21 
22 /*
23  * We use __attribute__((always_inline)) below so the compiler has visibility of
24  * the switch() at the call site. It is often the case that the size of multiple
25  * fields depends on the tag. Inlining thus gives the compiler visibility to
26  * hoist one tag-based code-path condition to cover all invocations.
27  */
28 
29 __attribute__((always_inline)) static inline int
30 pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf *ctx,
31 				enum pldm_sensor_readings_data_type tag,
32 				union_sensor_data_size *dst)
33 {
34 	switch (tag) {
35 	case PLDM_SENSOR_DATA_SIZE_UINT8:
36 		return pldm_msgbuf_extract(ctx, &dst->value_u8);
37 	case PLDM_SENSOR_DATA_SIZE_SINT8:
38 		return pldm_msgbuf_extract(ctx, &dst->value_s8);
39 	case PLDM_SENSOR_DATA_SIZE_UINT16:
40 		return pldm_msgbuf_extract(ctx, &dst->value_u16);
41 	case PLDM_SENSOR_DATA_SIZE_SINT16:
42 		return pldm_msgbuf_extract(ctx, &dst->value_s16);
43 	case PLDM_SENSOR_DATA_SIZE_UINT32:
44 		return pldm_msgbuf_extract(ctx, &dst->value_u32);
45 	case PLDM_SENSOR_DATA_SIZE_SINT32:
46 		return pldm_msgbuf_extract(ctx, &dst->value_s32);
47 	}
48 
49 	return -PLDM_ERROR_INVALID_DATA;
50 }
51 
52 /*
53  * This API is bad, but it's because the caller's APIs are also bad. They should
54  * have used the approach used by callers of pldm_msgbuf_extract_sensor_data()
55  * above
56  */
57 __attribute__((always_inline)) static inline int
58 pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx,
59 				 enum pldm_sensor_readings_data_type tag,
60 				 uint8_t *val)
61 {
62 	switch (tag) {
63 	case PLDM_SENSOR_DATA_SIZE_UINT8:
64 		return pldm_msgbuf_extract_uint8(ctx, (uint8_t *)val);
65 	case PLDM_SENSOR_DATA_SIZE_SINT8:
66 		return pldm_msgbuf_extract_int8(ctx, (int8_t *)val);
67 	case PLDM_SENSOR_DATA_SIZE_UINT16:
68 		return pldm_msgbuf_extract_uint16(ctx, (uint16_t *)val);
69 	case PLDM_SENSOR_DATA_SIZE_SINT16:
70 		return pldm_msgbuf_extract_int16(ctx, (int16_t *)val);
71 	case PLDM_SENSOR_DATA_SIZE_UINT32:
72 		return pldm_msgbuf_extract_uint32(ctx, (uint32_t *)val);
73 	case PLDM_SENSOR_DATA_SIZE_SINT32:
74 		return pldm_msgbuf_extract_int32(ctx, (int32_t *)val);
75 	}
76 
77 	return -PLDM_ERROR_INVALID_DATA;
78 }
79 
80 __attribute__((always_inline)) static inline int
81 pldm_msgbuf_extract_range_field_format(struct pldm_msgbuf *ctx,
82 				       enum pldm_range_field_format tag,
83 				       union_range_field_format *dst)
84 {
85 	switch (tag) {
86 	case PLDM_RANGE_FIELD_FORMAT_UINT8:
87 		return pldm_msgbuf_extract(ctx, &dst->value_u8);
88 	case PLDM_RANGE_FIELD_FORMAT_SINT8:
89 		return pldm_msgbuf_extract(ctx, &dst->value_s8);
90 	case PLDM_RANGE_FIELD_FORMAT_UINT16:
91 		return pldm_msgbuf_extract(ctx, &dst->value_u16);
92 	case PLDM_RANGE_FIELD_FORMAT_SINT16:
93 		return pldm_msgbuf_extract(ctx, &dst->value_s16);
94 	case PLDM_RANGE_FIELD_FORMAT_UINT32:
95 		return pldm_msgbuf_extract(ctx, &dst->value_u32);
96 	case PLDM_RANGE_FIELD_FORMAT_SINT32:
97 		return pldm_msgbuf_extract(ctx, &dst->value_s32);
98 	case PLDM_RANGE_FIELD_FORMAT_REAL32:
99 		return pldm_msgbuf_extract(ctx, &dst->value_f32);
100 	}
101 
102 	return -PLDM_ERROR_INVALID_DATA;
103 }
104 
105 /* This API is bad, but it's because the caller's APIs are also bad */
106 __attribute__((always_inline)) static inline int
107 pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx,
108 				   enum pldm_effecter_data_size tag,
109 				   uint8_t *val)
110 {
111 	switch (tag) {
112 	case PLDM_EFFECTER_DATA_SIZE_UINT8:
113 		return pldm_msgbuf_extract_uint8(ctx, (uint8_t *)val);
114 	case PLDM_EFFECTER_DATA_SIZE_SINT8:
115 		return pldm_msgbuf_extract_int8(ctx, (int8_t *)val);
116 	case PLDM_EFFECTER_DATA_SIZE_UINT16:
117 		return pldm_msgbuf_extract_uint16(ctx, (uint16_t *)val);
118 	case PLDM_EFFECTER_DATA_SIZE_SINT16:
119 		return pldm_msgbuf_extract_int16(ctx, (int16_t *)val);
120 	case PLDM_EFFECTER_DATA_SIZE_UINT32:
121 		return pldm_msgbuf_extract_uint32(ctx, (uint32_t *)val);
122 	case PLDM_EFFECTER_DATA_SIZE_SINT32:
123 		return pldm_msgbuf_extract_int32(ctx, (int32_t *)val);
124 	}
125 
126 	return -PLDM_ERROR_INVALID_DATA;
127 }
128 
129 #endif
130