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