xref: /openbmc/libpldm/src/msgbuf/platform.h (revision d4878cdf)
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
pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf * ctx,struct pldm_value_pdr_hdr * hdr)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
pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf * ctx,enum pldm_sensor_readings_data_type tag,union_sensor_data_size * dst)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
pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf * ctx,enum pldm_sensor_readings_data_type tag,void * val)58 pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx,
59 				 enum pldm_sensor_readings_data_type tag,
60 				 void *val)
61 {
62 	switch (tag) {
63 	case PLDM_SENSOR_DATA_SIZE_UINT8:
64 		return pldm__msgbuf_extract_uint8(ctx, val);
65 	case PLDM_SENSOR_DATA_SIZE_SINT8:
66 		return pldm__msgbuf_extract_int8(ctx, val);
67 	case PLDM_SENSOR_DATA_SIZE_UINT16:
68 		return pldm__msgbuf_extract_uint16(ctx, val);
69 	case PLDM_SENSOR_DATA_SIZE_SINT16:
70 		return pldm__msgbuf_extract_int16(ctx, val);
71 	case PLDM_SENSOR_DATA_SIZE_UINT32:
72 		return pldm__msgbuf_extract_uint32(ctx, val);
73 	case PLDM_SENSOR_DATA_SIZE_SINT32:
74 		return pldm__msgbuf_extract_int32(ctx, val);
75 	}
76 
77 	return -PLDM_ERROR_INVALID_DATA;
78 }
79 
80 #define pldm_msgbuf_extract_range_field_format(ctx, tag, dst)                  \
81 	pldm_msgbuf_extract_typecheck(union_range_field_format,                \
82 				      pldm__msgbuf_extract_range_field_format, \
83 				      dst, ctx, tag, (void *)&(dst))
84 __attribute__((always_inline)) static inline int
pldm__msgbuf_extract_range_field_format(struct pldm_msgbuf * ctx,enum pldm_range_field_format tag,void * rff)85 pldm__msgbuf_extract_range_field_format(struct pldm_msgbuf *ctx,
86 					enum pldm_range_field_format tag,
87 					void *rff)
88 {
89 	switch (tag) {
90 	case PLDM_RANGE_FIELD_FORMAT_UINT8:
91 		return pldm__msgbuf_extract_uint8(
92 			ctx, ((char *)rff) + offsetof(union_range_field_format,
93 						      value_u8));
94 	case PLDM_RANGE_FIELD_FORMAT_SINT8:
95 		return pldm__msgbuf_extract_int8(
96 			ctx, ((char *)rff) + offsetof(union_range_field_format,
97 						      value_s8));
98 	case PLDM_RANGE_FIELD_FORMAT_UINT16:
99 		return pldm__msgbuf_extract_uint16(
100 			ctx, ((char *)rff) + offsetof(union_range_field_format,
101 						      value_u16));
102 	case PLDM_RANGE_FIELD_FORMAT_SINT16:
103 		return pldm__msgbuf_extract_int16(
104 			ctx, ((char *)rff) + offsetof(union_range_field_format,
105 						      value_s16));
106 	case PLDM_RANGE_FIELD_FORMAT_UINT32:
107 		return pldm__msgbuf_extract_uint32(
108 			ctx, ((char *)rff) + offsetof(union_range_field_format,
109 						      value_u32));
110 	case PLDM_RANGE_FIELD_FORMAT_SINT32:
111 		return pldm__msgbuf_extract_int32(
112 			ctx, ((char *)rff) + offsetof(union_range_field_format,
113 						      value_s32));
114 	case PLDM_RANGE_FIELD_FORMAT_REAL32:
115 		return pldm__msgbuf_extract_real32(
116 			ctx, ((char *)rff) + offsetof(union_range_field_format,
117 						      value_f32));
118 	}
119 
120 	return -PLDM_ERROR_INVALID_DATA;
121 }
122 
123 /* This API is bad, but it's because the caller's APIs are also bad */
124 __attribute__((always_inline)) static inline int
pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf * ctx,enum pldm_effecter_data_size tag,void * dst)125 pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx,
126 				   enum pldm_effecter_data_size tag, void *dst)
127 {
128 	switch (tag) {
129 	case PLDM_EFFECTER_DATA_SIZE_UINT8:
130 		return pldm__msgbuf_extract_uint8(ctx, dst);
131 	case PLDM_EFFECTER_DATA_SIZE_SINT8:
132 		return pldm__msgbuf_extract_int8(ctx, dst);
133 	case PLDM_EFFECTER_DATA_SIZE_UINT16:
134 		return pldm__msgbuf_extract_uint16(ctx, dst);
135 	case PLDM_EFFECTER_DATA_SIZE_SINT16:
136 		return pldm__msgbuf_extract_int16(ctx, dst);
137 	case PLDM_EFFECTER_DATA_SIZE_UINT32:
138 		return pldm__msgbuf_extract_uint32(ctx, dst);
139 	case PLDM_EFFECTER_DATA_SIZE_SINT32:
140 		return pldm__msgbuf_extract_int32(ctx, dst);
141 	}
142 
143 	return -PLDM_ERROR_INVALID_DATA;
144 }
145 
146 #define pldm_msgbuf_extract_effecter_data(ctx, tag, dst)                       \
147 	pldm_msgbuf_extract_typecheck(union_effecter_data_size,                \
148 				      pldm__msgbuf_extract_range_field_format, \
149 				      dst, ctx, tag, (void *)&(dst))
150 __attribute__((always_inline)) static inline int
pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf * ctx,enum pldm_effecter_data_size tag,void * ed)151 pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf *ctx,
152 				   enum pldm_effecter_data_size tag, void *ed)
153 {
154 	switch (tag) {
155 	case PLDM_EFFECTER_DATA_SIZE_UINT8:
156 		return pldm__msgbuf_extract_uint8(
157 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
158 						     value_u8));
159 	case PLDM_EFFECTER_DATA_SIZE_SINT8:
160 		return pldm__msgbuf_extract_int8(
161 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
162 						     value_s8));
163 	case PLDM_EFFECTER_DATA_SIZE_UINT16:
164 		return pldm__msgbuf_extract_uint16(
165 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
166 						     value_u16));
167 	case PLDM_EFFECTER_DATA_SIZE_SINT16:
168 		return pldm__msgbuf_extract_int16(
169 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
170 						     value_s16));
171 	case PLDM_EFFECTER_DATA_SIZE_UINT32:
172 		return pldm__msgbuf_extract_uint32(
173 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
174 						     value_u32));
175 	case PLDM_EFFECTER_DATA_SIZE_SINT32:
176 		return pldm__msgbuf_extract_int32(
177 			ctx, ((char *)ed) + offsetof(union_effecter_data_size,
178 						     value_s32));
179 	}
180 
181 	return -PLDM_ERROR_INVALID_DATA;
182 }
183 
184 #ifdef __cplusplus
185 #include <type_traits>
186 
187 template <typename T>
pldm_msgbuf_typecheck_range_field_format(struct pldm_msgbuf * ctx,enum pldm_range_field_format tag,void * _rff)188 static inline int pldm_msgbuf_typecheck_range_field_format(
189 	struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff)
190 {
191 	static_assert(std::is_same<union_range_field_format, T>::value);
192 	return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff);
193 }
194 #endif
195 
196 #endif
197