blob: 897c1990dc8d522a28e7b9f8b6f2d4ae10e25f7d [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
Andrew Jefferycb569bc2024-09-01 09:38:09 +03005#include "../compiler.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09306#include "../msgbuf.h"
7#include <libpldm/base.h>
8#include <libpldm/platform.h>
9
Andrew Jeffery329176a2024-09-26 22:38:24 +093010LIBPLDM_CC_NONNULL
11LIBPLDM_CC_ALWAYS_INLINE int
Andrew Jeffery7992eb82023-04-06 16:13:53 +093012pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx,
Andrew Jeffery329176a2024-09-26 22:38:24 +093013 struct pldm_value_pdr_hdr *hdr, size_t lower,
14 size_t upper)
Andrew Jeffery7992eb82023-04-06 16:13:53 +093015{
Andrew Jeffery329176a2024-09-26 22:38:24 +093016 int rc;
17
Andrew Jeffery66c77232024-04-24 11:42:02 +093018 pldm_msgbuf_extract(ctx, hdr->record_handle);
19 pldm_msgbuf_extract(ctx, hdr->version);
20 pldm_msgbuf_extract(ctx, hdr->type);
21 pldm_msgbuf_extract(ctx, hdr->record_change_num);
Andrew Jeffery329176a2024-09-26 22:38:24 +093022 rc = pldm_msgbuf_extract(ctx, hdr->length);
23 if (rc) {
24 return rc;
25 }
Andrew Jeffery7992eb82023-04-06 16:13:53 +093026
Andrew Jeffery329176a2024-09-26 22:38:24 +093027 if (hdr->length + sizeof(*ctx) < lower) {
28 return -EOVERFLOW;
29 }
30
31 if (hdr->length > upper) {
32 return -EOVERFLOW;
33 }
34
35 return 0;
Andrew Jeffery7992eb82023-04-06 16:13:53 +093036}
37
Andrew Jefferycb569bc2024-09-01 09:38:09 +030038LIBPLDM_CC_ALWAYS_INLINE int
Andrew Jeffery7992eb82023-04-06 16:13:53 +093039pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf *ctx,
40 enum pldm_sensor_readings_data_type tag,
41 union_sensor_data_size *dst)
42{
43 switch (tag) {
44 case PLDM_SENSOR_DATA_SIZE_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093045 return pldm_msgbuf_extract(ctx, dst->value_u8);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093046 case PLDM_SENSOR_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093047 return pldm_msgbuf_extract(ctx, dst->value_s8);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093048 case PLDM_SENSOR_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093049 return pldm_msgbuf_extract(ctx, dst->value_u16);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093050 case PLDM_SENSOR_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093051 return pldm_msgbuf_extract(ctx, dst->value_s16);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093052 case PLDM_SENSOR_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093053 return pldm_msgbuf_extract(ctx, dst->value_u32);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093054 case PLDM_SENSOR_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093055 return pldm_msgbuf_extract(ctx, dst->value_s32);
Andrew Jeffery7992eb82023-04-06 16:13:53 +093056 }
57
58 return -PLDM_ERROR_INVALID_DATA;
59}
60
Andrew Jeffery840b1402023-04-13 23:54:44 +093061/*
62 * This API is bad, but it's because the caller's APIs are also bad. They should
63 * have used the approach used by callers of pldm_msgbuf_extract_sensor_data()
64 * above
65 */
Andrew Jefferycb569bc2024-09-01 09:38:09 +030066LIBPLDM_CC_ALWAYS_INLINE int
Andrew Jeffery840b1402023-04-13 23:54:44 +093067pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx,
Thu Nguyencd07fec2023-11-10 16:15:09 +070068 enum pldm_sensor_readings_data_type tag,
Andrew Jeffery66c77232024-04-24 11:42:02 +093069 void *val)
Andrew Jeffery840b1402023-04-13 23:54:44 +093070{
71 switch (tag) {
72 case PLDM_SENSOR_DATA_SIZE_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093073 return pldm__msgbuf_extract_uint8(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093074 case PLDM_SENSOR_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093075 return pldm__msgbuf_extract_int8(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093076 case PLDM_SENSOR_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093077 return pldm__msgbuf_extract_uint16(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093078 case PLDM_SENSOR_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +093079 return pldm__msgbuf_extract_int16(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093080 case PLDM_SENSOR_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093081 return pldm__msgbuf_extract_uint32(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093082 case PLDM_SENSOR_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +093083 return pldm__msgbuf_extract_int32(ctx, val);
Andrew Jeffery840b1402023-04-13 23:54:44 +093084 }
85
86 return -PLDM_ERROR_INVALID_DATA;
87}
88
Andrew Jeffery66c77232024-04-24 11:42:02 +093089#define pldm_msgbuf_extract_range_field_format(ctx, tag, dst) \
90 pldm_msgbuf_extract_typecheck(union_range_field_format, \
91 pldm__msgbuf_extract_range_field_format, \
92 dst, ctx, tag, (void *)&(dst))
Andrew Jefferycb569bc2024-09-01 09:38:09 +030093LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_extract_range_field_format(
94 struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *rff)
Andrew Jeffery7992eb82023-04-06 16:13:53 +093095{
96 switch (tag) {
97 case PLDM_RANGE_FIELD_FORMAT_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +093098 return pldm__msgbuf_extract_uint8(
99 ctx, ((char *)rff) + offsetof(union_range_field_format,
100 value_u8));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930101 case PLDM_RANGE_FIELD_FORMAT_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930102 return pldm__msgbuf_extract_int8(
103 ctx, ((char *)rff) + offsetof(union_range_field_format,
104 value_s8));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930105 case PLDM_RANGE_FIELD_FORMAT_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930106 return pldm__msgbuf_extract_uint16(
107 ctx, ((char *)rff) + offsetof(union_range_field_format,
108 value_u16));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930109 case PLDM_RANGE_FIELD_FORMAT_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930110 return pldm__msgbuf_extract_int16(
111 ctx, ((char *)rff) + offsetof(union_range_field_format,
112 value_s16));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930113 case PLDM_RANGE_FIELD_FORMAT_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930114 return pldm__msgbuf_extract_uint32(
115 ctx, ((char *)rff) + offsetof(union_range_field_format,
116 value_u32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930117 case PLDM_RANGE_FIELD_FORMAT_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930118 return pldm__msgbuf_extract_int32(
119 ctx, ((char *)rff) + offsetof(union_range_field_format,
120 value_s32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930121 case PLDM_RANGE_FIELD_FORMAT_REAL32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930122 return pldm__msgbuf_extract_real32(
123 ctx, ((char *)rff) + offsetof(union_range_field_format,
124 value_f32));
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930125 }
126
127 return -PLDM_ERROR_INVALID_DATA;
128}
129
Andrew Jeffery3884c442023-04-12 11:13:24 +0930130/* This API is bad, but it's because the caller's APIs are also bad */
Andrew Jefferycb569bc2024-09-01 09:38:09 +0300131LIBPLDM_CC_ALWAYS_INLINE int
Andrew Jeffery3884c442023-04-12 11:13:24 +0930132pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx,
Andrew Jeffery66c77232024-04-24 11:42:02 +0930133 enum pldm_effecter_data_size tag, void *dst)
Andrew Jeffery3884c442023-04-12 11:13:24 +0930134{
135 switch (tag) {
136 case PLDM_EFFECTER_DATA_SIZE_UINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930137 return pldm__msgbuf_extract_uint8(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930138 case PLDM_EFFECTER_DATA_SIZE_SINT8:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930139 return pldm__msgbuf_extract_int8(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930140 case PLDM_EFFECTER_DATA_SIZE_UINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930141 return pldm__msgbuf_extract_uint16(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930142 case PLDM_EFFECTER_DATA_SIZE_SINT16:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930143 return pldm__msgbuf_extract_int16(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930144 case PLDM_EFFECTER_DATA_SIZE_UINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930145 return pldm__msgbuf_extract_uint32(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930146 case PLDM_EFFECTER_DATA_SIZE_SINT32:
Andrew Jeffery66c77232024-04-24 11:42:02 +0930147 return pldm__msgbuf_extract_int32(ctx, dst);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930148 }
149
150 return -PLDM_ERROR_INVALID_DATA;
151}
152
Thu Nguyend4878cd2023-11-09 10:18:33 +0700153#define pldm_msgbuf_extract_effecter_data(ctx, tag, dst) \
154 pldm_msgbuf_extract_typecheck(union_effecter_data_size, \
155 pldm__msgbuf_extract_range_field_format, \
156 dst, ctx, tag, (void *)&(dst))
Andrew Jefferycb569bc2024-09-01 09:38:09 +0300157LIBPLDM_CC_ALWAYS_INLINE int
Thu Nguyend4878cd2023-11-09 10:18:33 +0700158pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf *ctx,
159 enum pldm_effecter_data_size tag, void *ed)
160{
161 switch (tag) {
162 case PLDM_EFFECTER_DATA_SIZE_UINT8:
163 return pldm__msgbuf_extract_uint8(
164 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
165 value_u8));
166 case PLDM_EFFECTER_DATA_SIZE_SINT8:
167 return pldm__msgbuf_extract_int8(
168 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
169 value_s8));
170 case PLDM_EFFECTER_DATA_SIZE_UINT16:
171 return pldm__msgbuf_extract_uint16(
172 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
173 value_u16));
174 case PLDM_EFFECTER_DATA_SIZE_SINT16:
175 return pldm__msgbuf_extract_int16(
176 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
177 value_s16));
178 case PLDM_EFFECTER_DATA_SIZE_UINT32:
179 return pldm__msgbuf_extract_uint32(
180 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
181 value_u32));
182 case PLDM_EFFECTER_DATA_SIZE_SINT32:
183 return pldm__msgbuf_extract_int32(
184 ctx, ((char *)ed) + offsetof(union_effecter_data_size,
185 value_s32));
186 }
187
188 return -PLDM_ERROR_INVALID_DATA;
189}
190
Andrew Jeffery66c77232024-04-24 11:42:02 +0930191#ifdef __cplusplus
192#include <type_traits>
193
194template <typename T>
195static inline int pldm_msgbuf_typecheck_range_field_format(
196 struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff)
197{
198 static_assert(std::is_same<union_range_field_format, T>::value);
199 return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff);
200}
201#endif
202
Andrew Jeffery7992eb82023-04-06 16:13:53 +0930203#endif