blob: c52a66dd172625711de2bcf68c9c5549083dd0fd [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Andrew Jeffery7992eb82023-04-06 16:13:53 +09302#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
9static inline int
10pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx,
11 struct pldm_value_pdr_hdr *hdr)
12{
Andrew Jeffery66c77232024-04-24 11:42:02 +093013 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);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093018
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
30pldm_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:
Andrew Jeffery66c77232024-04-24 11:42:02 +093036 return pldm_msgbuf_extract(ctx, dst->value_u8);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093037 case PLDM_SENSOR_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093038 return pldm_msgbuf_extract(ctx, dst->value_s8);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093039 case PLDM_SENSOR_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093040 return pldm_msgbuf_extract(ctx, dst->value_u16);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093041 case PLDM_SENSOR_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093042 return pldm_msgbuf_extract(ctx, dst->value_s16);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093043 case PLDM_SENSOR_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093044 return pldm_msgbuf_extract(ctx, dst->value_u32);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093045 case PLDM_SENSOR_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093046 return pldm_msgbuf_extract(ctx, dst->value_s32);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093047 }
48
49 return -PLDM_ERROR_INVALID_DATA;
50}
51
Andrew Jeffery840b1402023-04-13 23:54:44 +093052/*
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
58pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx,
Thu Nguyencd07fec2023-11-10 16:15:09 +070059 enum pldm_sensor_readings_data_type tag,
Andrew Jeffery66c77232024-04-24 11:42:02 +093060 void *val)
Andrew Jeffery840b1402023-04-13 23:54:44 +093061{
62 switch (tag) {
63 case PLDM_SENSOR_DATA_SIZE_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093064 return pldm__msgbuf_extract_uint8(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093065 case PLDM_SENSOR_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093066 return pldm__msgbuf_extract_int8(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093067 case PLDM_SENSOR_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093068 return pldm__msgbuf_extract_uint16(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093069 case PLDM_SENSOR_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093070 return pldm__msgbuf_extract_int16(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093071 case PLDM_SENSOR_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093072 return pldm__msgbuf_extract_uint32(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093073 case PLDM_SENSOR_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093074 return pldm__msgbuf_extract_int32(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093075 }
76
77 return -PLDM_ERROR_INVALID_DATA;
78}
79
Andrew Jeffery66c77232024-04-24 11:42:02 +093080#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))
Andrew Jeffery7992eb82023-04-06 16:13:53 +093084__attribute__((always_inline)) static inline int
Andrew Jeffery66c77232024-04-24 11:42:02 +093085pldm__msgbuf_extract_range_field_format(struct pldm_msgbuf *ctx,
86 enum pldm_range_field_format tag,
87 void *rff)
Andrew Jeffery7992eb82023-04-06 16:13:53 +093088{
89 switch (tag) {
90 case PLDM_RANGE_FIELD_FORMAT_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093091 return pldm__msgbuf_extract_uint8(
92 ctx, ((char *)rff) + offsetof(union_range_field_format,
93 value_u8));
Andrew Jeffery7992eb82023-04-06 16:13:53 +093094 case PLDM_RANGE_FIELD_FORMAT_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093095 return pldm__msgbuf_extract_int8(
96 ctx, ((char *)rff) + offsetof(union_range_field_format,
97 value_s8));
Andrew Jeffery7992eb82023-04-06 16:13:53 +093098 case PLDM_RANGE_FIELD_FORMAT_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093099 return pldm__msgbuf_extract_uint16(
100 ctx, ((char *)rff) + offsetof(union_range_field_format,
101 value_u16));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930102 case PLDM_RANGE_FIELD_FORMAT_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930103 return pldm__msgbuf_extract_int16(
104 ctx, ((char *)rff) + offsetof(union_range_field_format,
105 value_s16));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930106 case PLDM_RANGE_FIELD_FORMAT_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930107 return pldm__msgbuf_extract_uint32(
108 ctx, ((char *)rff) + offsetof(union_range_field_format,
109 value_u32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930110 case PLDM_RANGE_FIELD_FORMAT_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930111 return pldm__msgbuf_extract_int32(
112 ctx, ((char *)rff) + offsetof(union_range_field_format,
113 value_s32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930114 case PLDM_RANGE_FIELD_FORMAT_REAL32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930115 return pldm__msgbuf_extract_real32(
116 ctx, ((char *)rff) + offsetof(union_range_field_format,
117 value_f32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930118 }
119
120 return -PLDM_ERROR_INVALID_DATA;
121}
122
Andrew Jeffery3884c442023-04-12 11:13:24 +0930123/* This API is bad, but it's because the caller's APIs are also bad */
124__attribute__((always_inline)) static inline int
125pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx,
Andrew Jeffery66c77232024-04-24 11:42:02 +0930126 enum pldm_effecter_data_size tag, void *dst)
Andrew Jeffery3884c442023-04-12 11:13:24 +0930127{
128 switch (tag) {
129 case PLDM_EFFECTER_DATA_SIZE_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930130 return pldm__msgbuf_extract_uint8(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930131 case PLDM_EFFECTER_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930132 return pldm__msgbuf_extract_int8(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930133 case PLDM_EFFECTER_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930134 return pldm__msgbuf_extract_uint16(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930135 case PLDM_EFFECTER_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930136 return pldm__msgbuf_extract_int16(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930137 case PLDM_EFFECTER_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930138 return pldm__msgbuf_extract_uint32(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930139 case PLDM_EFFECTER_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930140 return pldm__msgbuf_extract_int32(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930141 }
142
143 return -PLDM_ERROR_INVALID_DATA;
144}
145
Thu Nguyend4878cd2023-11-09 10:18:33 +0700146#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
151pldm__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
Andrew Jeffery66c77232024-04-24 11:42:02 +0930184#ifdef __cplusplus
185#include <type_traits>
186
187template <typename T>
188static 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
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930196#endif