1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include "utils.h"
3
4 #include <libpldm/base.h>
5 #include <libpldm/bios.h>
6 #include <libpldm/utils.h>
7
8 #include <endian.h>
9 #include <string.h>
10
11 LIBPLDM_ABI_STABLE
encode_get_date_time_req(uint8_t instance_id,struct pldm_msg * msg)12 int encode_get_date_time_req(uint8_t instance_id, struct pldm_msg *msg)
13 {
14 if (msg == NULL) {
15 return PLDM_ERROR_INVALID_DATA;
16 }
17
18 struct pldm_header_info header = { 0 };
19 header.msg_type = PLDM_REQUEST;
20 header.instance = instance_id;
21 header.pldm_type = PLDM_BIOS;
22 header.command = PLDM_GET_DATE_TIME;
23 return pack_pldm_header(&header, &(msg->hdr));
24 }
25
26 LIBPLDM_ABI_STABLE
encode_get_date_time_resp(uint8_t instance_id,uint8_t completion_code,uint8_t seconds,uint8_t minutes,uint8_t hours,uint8_t day,uint8_t month,uint16_t year,struct pldm_msg * msg)27 int encode_get_date_time_resp(uint8_t instance_id, uint8_t completion_code,
28 uint8_t seconds, uint8_t minutes, uint8_t hours,
29 uint8_t day, uint8_t month, uint16_t year,
30 struct pldm_msg *msg)
31 {
32 if (msg == NULL) {
33 return PLDM_ERROR_INVALID_DATA;
34 }
35
36 struct pldm_header_info header = { 0 };
37 header.msg_type = PLDM_RESPONSE;
38 header.instance = instance_id;
39 header.pldm_type = PLDM_BIOS;
40 header.command = PLDM_GET_DATE_TIME;
41
42 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
43 if (rc != PLDM_SUCCESS) {
44 return rc;
45 }
46
47 struct pldm_get_date_time_resp *response =
48 (struct pldm_get_date_time_resp *)msg->payload;
49 response->completion_code = completion_code;
50 if (response->completion_code == PLDM_SUCCESS) {
51 response->completion_code = completion_code;
52 response->seconds = seconds;
53 response->minutes = minutes;
54 response->hours = hours;
55 response->day = day;
56 response->month = month;
57 response->year = htole16(year);
58 }
59 return PLDM_SUCCESS;
60 }
61
62 LIBPLDM_ABI_STABLE
decode_get_date_time_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * seconds,uint8_t * minutes,uint8_t * hours,uint8_t * day,uint8_t * month,uint16_t * year)63 int decode_get_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
64 uint8_t *completion_code, uint8_t *seconds,
65 uint8_t *minutes, uint8_t *hours, uint8_t *day,
66 uint8_t *month, uint16_t *year)
67 {
68 if (msg == NULL || seconds == NULL || minutes == NULL ||
69 hours == NULL || day == NULL || month == NULL || year == NULL ||
70 completion_code == NULL) {
71 return PLDM_ERROR_INVALID_DATA;
72 }
73
74 *completion_code = msg->payload[0];
75 if (PLDM_SUCCESS != *completion_code) {
76 return PLDM_SUCCESS;
77 }
78
79 if (payload_length != PLDM_GET_DATE_TIME_RESP_BYTES) {
80 return PLDM_ERROR_INVALID_LENGTH;
81 }
82
83 struct pldm_get_date_time_resp *response =
84 (struct pldm_get_date_time_resp *)msg->payload;
85
86 *seconds = response->seconds;
87 *minutes = response->minutes;
88 *hours = response->hours;
89 *day = response->day;
90 *month = response->month;
91 *year = le16toh(response->year);
92
93 return PLDM_SUCCESS;
94 }
95
96 LIBPLDM_ABI_STABLE
encode_set_date_time_req(uint8_t instance_id,uint8_t seconds,uint8_t minutes,uint8_t hours,uint8_t day,uint8_t month,uint16_t year,struct pldm_msg * msg,size_t payload_length)97 int encode_set_date_time_req(uint8_t instance_id, uint8_t seconds,
98 uint8_t minutes, uint8_t hours, uint8_t day,
99 uint8_t month, uint16_t year, struct pldm_msg *msg,
100 size_t payload_length)
101 {
102 if (msg == NULL) {
103 return PLDM_ERROR_INVALID_DATA;
104 }
105 if (payload_length != sizeof(struct pldm_set_date_time_req)) {
106 return PLDM_ERROR_INVALID_LENGTH;
107 }
108
109 if (!is_time_legal(seconds, minutes, hours, day, month, year)) {
110 return PLDM_ERROR_INVALID_DATA;
111 }
112
113 struct pldm_header_info header = { 0 };
114 header.instance = instance_id;
115 header.msg_type = PLDM_REQUEST;
116 header.pldm_type = PLDM_BIOS;
117 header.command = PLDM_SET_DATE_TIME;
118
119 uint8_t rc = pack_pldm_header(&header, &msg->hdr);
120 if (rc != PLDM_SUCCESS) {
121 return rc;
122 }
123
124 struct pldm_set_date_time_req *request =
125 (struct pldm_set_date_time_req *)msg->payload;
126 request->seconds = pldm_bcd_dec2bcd8(seconds);
127 request->minutes = pldm_bcd_dec2bcd8(minutes);
128 request->hours = pldm_bcd_dec2bcd8(hours);
129 request->day = pldm_bcd_dec2bcd8(day);
130 request->month = pldm_bcd_dec2bcd8(month);
131 request->year = htole16(pldm_bcd_dec2bcd16(year));
132
133 return PLDM_SUCCESS;
134 }
135
136 LIBPLDM_ABI_STABLE
decode_set_date_time_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * seconds,uint8_t * minutes,uint8_t * hours,uint8_t * day,uint8_t * month,uint16_t * year)137 int decode_set_date_time_req(const struct pldm_msg *msg, size_t payload_length,
138 uint8_t *seconds, uint8_t *minutes, uint8_t *hours,
139 uint8_t *day, uint8_t *month, uint16_t *year)
140 {
141 if (msg == NULL || seconds == NULL || minutes == NULL ||
142 hours == NULL || day == NULL || month == NULL || year == NULL) {
143 return PLDM_ERROR_INVALID_DATA;
144 }
145 if (payload_length != sizeof(struct pldm_set_date_time_req)) {
146 return PLDM_ERROR_INVALID_LENGTH;
147 }
148
149 const struct pldm_set_date_time_req *request =
150 (struct pldm_set_date_time_req *)msg->payload;
151
152 *seconds = pldm_bcd_bcd2dec8(request->seconds);
153 *minutes = pldm_bcd_bcd2dec8(request->minutes);
154 *hours = pldm_bcd_bcd2dec8(request->hours);
155 *day = pldm_bcd_bcd2dec8(request->day);
156 *month = pldm_bcd_bcd2dec8(request->month);
157 *year = pldm_bcd_bcd2dec16(le16toh(request->year));
158
159 if (!is_time_legal(*seconds, *minutes, *hours, *day, *month, *year)) {
160 return PLDM_ERROR_INVALID_DATA;
161 }
162
163 return PLDM_SUCCESS;
164 }
165
166 LIBPLDM_ABI_STABLE
encode_set_date_time_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg,size_t payload_length)167 int encode_set_date_time_resp(uint8_t instance_id, uint8_t completion_code,
168 struct pldm_msg *msg, size_t payload_length)
169 {
170 if (msg == NULL) {
171 return PLDM_ERROR_INVALID_DATA;
172 }
173 if (payload_length != sizeof(struct pldm_only_cc_resp)) {
174 return PLDM_ERROR_INVALID_LENGTH;
175 }
176
177 struct pldm_header_info header = { 0 };
178 header.instance = instance_id;
179 header.msg_type = PLDM_RESPONSE;
180 header.pldm_type = PLDM_BIOS;
181 header.command = PLDM_SET_DATE_TIME;
182
183 uint8_t rc = pack_pldm_header(&header, &msg->hdr);
184 if (rc != PLDM_SUCCESS) {
185 return rc;
186 }
187
188 struct pldm_only_cc_resp *response =
189 (struct pldm_only_cc_resp *)msg->payload;
190 response->completion_code = completion_code;
191
192 return PLDM_SUCCESS;
193 }
194
195 LIBPLDM_ABI_STABLE
decode_set_date_time_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)196 int decode_set_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
197 uint8_t *completion_code)
198 {
199 if (msg == NULL || completion_code == NULL) {
200 return PLDM_ERROR_INVALID_DATA;
201 }
202
203 *completion_code = msg->payload[0];
204 if (PLDM_SUCCESS != *completion_code) {
205 return PLDM_SUCCESS;
206 }
207
208 if (payload_length != sizeof(struct pldm_only_cc_resp)) {
209 return PLDM_ERROR_INVALID_LENGTH;
210 }
211
212 return PLDM_SUCCESS;
213 }
214
215 LIBPLDM_ABI_DEPRECATED_UNSAFE
encode_get_bios_table_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,uint8_t transfer_flag,uint8_t * table_data,size_t payload_length,struct pldm_msg * msg)216 int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
217 uint32_t next_transfer_handle,
218 uint8_t transfer_flag, uint8_t *table_data,
219 size_t payload_length, struct pldm_msg *msg)
220 {
221 if (msg == NULL) {
222 return PLDM_ERROR_INVALID_DATA;
223 }
224
225 struct pldm_header_info header = { 0 };
226 header.msg_type = PLDM_RESPONSE;
227 header.instance = instance_id;
228 header.pldm_type = PLDM_BIOS;
229 header.command = PLDM_GET_BIOS_TABLE;
230
231 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
232 if (rc != PLDM_SUCCESS) {
233 return rc;
234 }
235
236 struct pldm_get_bios_table_resp *response =
237 (struct pldm_get_bios_table_resp *)msg->payload;
238 response->completion_code = completion_code;
239 if (response->completion_code == PLDM_SUCCESS) {
240 response->next_transfer_handle = htole32(next_transfer_handle);
241 response->transfer_flag = transfer_flag;
242 if (table_data != NULL &&
243 payload_length > (sizeof(struct pldm_msg_hdr) +
244 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES)) {
245 memcpy(response->table_data, table_data,
246 payload_length -
247 (sizeof(struct pldm_msg_hdr) +
248 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES));
249 }
250 }
251 return PLDM_SUCCESS;
252 }
253
254 LIBPLDM_ABI_STABLE
encode_get_bios_table_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_op_flag,uint8_t table_type,struct pldm_msg * msg)255 int encode_get_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
256 uint8_t transfer_op_flag, uint8_t table_type,
257 struct pldm_msg *msg)
258 {
259 if (msg == NULL) {
260 return PLDM_ERROR_INVALID_DATA;
261 }
262
263 struct pldm_header_info header = { 0 };
264 header.msg_type = PLDM_REQUEST;
265 header.instance = instance_id;
266 header.pldm_type = PLDM_BIOS;
267 header.command = PLDM_GET_BIOS_TABLE;
268
269 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
270 if (rc != PLDM_SUCCESS) {
271 return rc;
272 }
273
274 struct pldm_get_bios_table_req *request =
275 (struct pldm_get_bios_table_req *)msg->payload;
276
277 request->transfer_handle = htole32(transfer_handle);
278 request->transfer_op_flag = transfer_op_flag;
279 request->table_type = table_type;
280 return PLDM_SUCCESS;
281 }
282
283 LIBPLDM_ABI_STABLE
decode_get_bios_table_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_op_flag,uint8_t * table_type)284 int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
285 uint32_t *transfer_handle,
286 uint8_t *transfer_op_flag, uint8_t *table_type)
287 {
288 if (msg == NULL || transfer_op_flag == NULL || table_type == NULL ||
289 transfer_handle == NULL) {
290 return PLDM_ERROR_INVALID_DATA;
291 }
292
293 if (payload_length != PLDM_GET_BIOS_TABLE_REQ_BYTES) {
294 return PLDM_ERROR_INVALID_LENGTH;
295 }
296
297 struct pldm_get_bios_table_req *request =
298 (struct pldm_get_bios_table_req *)msg->payload;
299 *transfer_handle = le32toh(request->transfer_handle);
300 *transfer_op_flag = request->transfer_op_flag;
301 *table_type = request->table_type;
302
303 return PLDM_SUCCESS;
304 }
305
306 LIBPLDM_ABI_STABLE
decode_get_bios_table_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle,uint8_t * transfer_flag,size_t * bios_table_offset)307 int decode_get_bios_table_resp(const struct pldm_msg *msg,
308 size_t payload_length, uint8_t *completion_code,
309 uint32_t *next_transfer_handle,
310 uint8_t *transfer_flag,
311 size_t *bios_table_offset)
312
313 {
314 if (msg == NULL || transfer_flag == NULL ||
315 next_transfer_handle == NULL || completion_code == NULL) {
316 return PLDM_ERROR_INVALID_DATA;
317 }
318 if (payload_length <= PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES) {
319 return PLDM_ERROR_INVALID_LENGTH;
320 }
321
322 struct pldm_get_bios_table_resp *response =
323 (struct pldm_get_bios_table_resp *)msg->payload;
324
325 *completion_code = response->completion_code;
326
327 if (PLDM_SUCCESS != *completion_code) {
328 return PLDM_SUCCESS;
329 }
330
331 *next_transfer_handle = le32toh(response->next_transfer_handle);
332 *transfer_flag = response->transfer_flag;
333
334 *bios_table_offset = sizeof(*completion_code) +
335 sizeof(*next_transfer_handle) +
336 sizeof(*transfer_flag);
337
338 return PLDM_SUCCESS;
339 }
340
341 LIBPLDM_ABI_STABLE
encode_get_bios_attribute_current_value_by_handle_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_op_flag,uint16_t attribute_handle,struct pldm_msg * msg)342 int encode_get_bios_attribute_current_value_by_handle_req(
343 uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
344 uint16_t attribute_handle, struct pldm_msg *msg)
345 {
346 if (msg == NULL) {
347 return PLDM_ERROR_INVALID_DATA;
348 }
349
350 struct pldm_header_info header = { 0 };
351 header.msg_type = PLDM_REQUEST;
352 header.instance = instance_id;
353 header.pldm_type = PLDM_BIOS;
354 header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
355
356 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
357 if (rc != PLDM_SUCCESS) {
358 return rc;
359 }
360
361 struct pldm_get_bios_attribute_current_value_by_handle_req *request =
362 (struct pldm_get_bios_attribute_current_value_by_handle_req *)
363 msg->payload;
364
365 request->transfer_handle = htole32(transfer_handle);
366 request->transfer_op_flag = transfer_op_flag;
367 request->attribute_handle = htole16(attribute_handle);
368 return PLDM_SUCCESS;
369 }
370
371 LIBPLDM_ABI_STABLE
decode_get_bios_attribute_current_value_by_handle_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle,uint8_t * transfer_flag,struct variable_field * attribute_data)372 int decode_get_bios_attribute_current_value_by_handle_resp(
373 const struct pldm_msg *msg, size_t payload_length,
374 uint8_t *completion_code, uint32_t *next_transfer_handle,
375 uint8_t *transfer_flag, struct variable_field *attribute_data)
376 {
377 if (msg == NULL || transfer_flag == NULL ||
378 next_transfer_handle == NULL || completion_code == NULL) {
379 return PLDM_ERROR_INVALID_DATA;
380 }
381
382 struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
383 (struct pldm_get_bios_attribute_current_value_by_handle_resp *)
384 msg->payload;
385
386 *completion_code = response->completion_code;
387
388 if (PLDM_SUCCESS != *completion_code) {
389 return PLDM_SUCCESS;
390 }
391
392 if (payload_length <=
393 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES) {
394 return PLDM_ERROR_INVALID_LENGTH;
395 }
396
397 *next_transfer_handle = le32toh(response->next_transfer_handle);
398 *transfer_flag = response->transfer_flag;
399
400 attribute_data->ptr = response->attribute_data;
401 attribute_data->length = payload_length - sizeof(*response) + 1;
402
403 return PLDM_SUCCESS;
404 }
405
406 LIBPLDM_ABI_STABLE
decode_get_bios_attribute_current_value_by_handle_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_op_flag,uint16_t * attribute_handle)407 int decode_get_bios_attribute_current_value_by_handle_req(
408 const struct pldm_msg *msg, size_t payload_length,
409 uint32_t *transfer_handle, uint8_t *transfer_op_flag,
410 uint16_t *attribute_handle)
411 {
412 if (msg == NULL || transfer_handle == NULL ||
413 transfer_op_flag == NULL || attribute_handle == NULL) {
414 return PLDM_ERROR_INVALID_DATA;
415 }
416
417 if (payload_length != PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES) {
418 return PLDM_ERROR_INVALID_LENGTH;
419 }
420
421 struct pldm_get_bios_attribute_current_value_by_handle_req *request =
422 (struct pldm_get_bios_attribute_current_value_by_handle_req *)
423 msg->payload;
424 *transfer_handle = le32toh(request->transfer_handle);
425 *transfer_op_flag = request->transfer_op_flag;
426 *attribute_handle = le16toh(request->attribute_handle);
427
428 return PLDM_SUCCESS;
429 }
430
431 LIBPLDM_ABI_DEPRECATED_UNSAFE
encode_get_bios_current_value_by_handle_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,uint8_t transfer_flag,const uint8_t * attribute_data,size_t attribute_length,struct pldm_msg * msg)432 int encode_get_bios_current_value_by_handle_resp(uint8_t instance_id,
433 uint8_t completion_code,
434 uint32_t next_transfer_handle,
435 uint8_t transfer_flag,
436 const uint8_t *attribute_data,
437 size_t attribute_length,
438 struct pldm_msg *msg)
439 {
440 if (msg == NULL || attribute_data == NULL) {
441 return PLDM_ERROR_INVALID_DATA;
442 }
443
444 struct pldm_header_info header = { 0 };
445 header.msg_type = PLDM_RESPONSE;
446 header.instance = instance_id;
447 header.pldm_type = PLDM_BIOS;
448 header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
449
450 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
451 if (rc != PLDM_SUCCESS) {
452 return rc;
453 }
454
455 struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
456 (struct pldm_get_bios_attribute_current_value_by_handle_resp *)
457 msg->payload;
458 response->completion_code = completion_code;
459 if (response->completion_code == PLDM_SUCCESS) {
460 response->next_transfer_handle = htole32(next_transfer_handle);
461 response->transfer_flag = transfer_flag;
462 if (attribute_data != NULL) {
463 memcpy(response->attribute_data, attribute_data,
464 attribute_length);
465 }
466 }
467 return PLDM_SUCCESS;
468 }
469
470 LIBPLDM_ABI_STABLE
encode_set_bios_attribute_current_value_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_flag,const uint8_t * attribute_data,size_t attribute_length,struct pldm_msg * msg,size_t payload_length)471 int encode_set_bios_attribute_current_value_req(
472 uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_flag,
473 const uint8_t *attribute_data, size_t attribute_length,
474 struct pldm_msg *msg, size_t payload_length)
475 {
476 if (msg == NULL || attribute_data == NULL) {
477 return PLDM_ERROR_INVALID_DATA;
478 }
479
480 if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
481 return PLDM_ERROR_INVALID_LENGTH;
482 }
483
484 if (payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES <
485 attribute_length) {
486 return PLDM_ERROR_INVALID_LENGTH;
487 }
488
489 struct pldm_header_info header = { 0 };
490 header.instance = instance_id;
491 header.msg_type = PLDM_REQUEST;
492 header.pldm_type = PLDM_BIOS;
493 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
494
495 uint8_t rc = pack_pldm_header(&header, &msg->hdr);
496 if (rc != PLDM_SUCCESS) {
497 return rc;
498 }
499
500 struct pldm_set_bios_attribute_current_value_req *request =
501 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
502 request->transfer_handle = htole32(transfer_handle);
503 request->transfer_flag = transfer_flag;
504 memcpy(request->attribute_data, attribute_data, attribute_length);
505
506 return PLDM_SUCCESS;
507 }
508
509 LIBPLDM_ABI_STABLE
decode_set_bios_attribute_current_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle)510 int decode_set_bios_attribute_current_value_resp(const struct pldm_msg *msg,
511 size_t payload_length,
512 uint8_t *completion_code,
513 uint32_t *next_transfer_handle)
514 {
515 if (msg == NULL || completion_code == NULL ||
516 next_transfer_handle == NULL) {
517 return PLDM_ERROR_INVALID_DATA;
518 }
519
520 *completion_code = msg->payload[0];
521 if (PLDM_SUCCESS != *completion_code) {
522 return PLDM_SUCCESS;
523 }
524
525 if (payload_length != PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES) {
526 return PLDM_ERROR_INVALID_LENGTH;
527 }
528
529 struct pldm_set_bios_attribute_current_value_resp *response =
530 (struct pldm_set_bios_attribute_current_value_resp *)
531 msg->payload;
532
533 *next_transfer_handle = le32toh(response->next_transfer_handle);
534
535 return PLDM_SUCCESS;
536 }
537
538 LIBPLDM_ABI_STABLE
decode_set_bios_attribute_current_value_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_flag,struct variable_field * attribute)539 int decode_set_bios_attribute_current_value_req(
540 const struct pldm_msg *msg, size_t payload_length,
541 uint32_t *transfer_handle, uint8_t *transfer_flag,
542 struct variable_field *attribute)
543 {
544 if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
545 attribute == NULL) {
546 return PLDM_ERROR_INVALID_DATA;
547 }
548 if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
549 return PLDM_ERROR_INVALID_LENGTH;
550 }
551
552 struct pldm_set_bios_attribute_current_value_req *request =
553 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
554 *transfer_handle = le32toh(request->transfer_handle);
555 *transfer_flag = request->transfer_flag;
556 attribute->length =
557 payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES;
558 attribute->ptr = request->attribute_data;
559 return PLDM_SUCCESS;
560 }
561
562 LIBPLDM_ABI_STABLE
encode_set_bios_attribute_current_value_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,struct pldm_msg * msg)563 int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
564 uint8_t completion_code,
565 uint32_t next_transfer_handle,
566 struct pldm_msg *msg)
567 {
568 if (msg == NULL) {
569 return PLDM_ERROR_INVALID_DATA;
570 }
571 struct pldm_header_info header = { 0 };
572 header.instance = instance_id;
573 header.msg_type = PLDM_RESPONSE;
574 header.pldm_type = PLDM_BIOS;
575 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
576
577 uint8_t rc = pack_pldm_header(&header, &msg->hdr);
578 if (rc != PLDM_SUCCESS) {
579 return rc;
580 }
581
582 struct pldm_set_bios_attribute_current_value_resp *response =
583 (struct pldm_set_bios_attribute_current_value_resp *)
584 msg->payload;
585 response->completion_code = completion_code;
586 response->next_transfer_handle = htole32(next_transfer_handle);
587
588 return PLDM_SUCCESS;
589 }
590
591 LIBPLDM_ABI_STABLE
encode_set_bios_table_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_flag,uint8_t table_type,const uint8_t * table_data,size_t table_length,struct pldm_msg * msg,size_t payload_length)592 int encode_set_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
593 uint8_t transfer_flag, uint8_t table_type,
594 const uint8_t *table_data, size_t table_length,
595 struct pldm_msg *msg, size_t payload_length)
596 {
597 if (msg == NULL || table_data == NULL) {
598 return PLDM_ERROR_INVALID_DATA;
599 }
600
601 if (payload_length < PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES) {
602 return PLDM_ERROR_INVALID_LENGTH;
603 }
604
605 if (payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES < table_length) {
606 return PLDM_ERROR_INVALID_LENGTH;
607 }
608
609 if (payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES > table_length) {
610 return PLDM_ERROR_INVALID_LENGTH;
611 }
612
613 struct pldm_header_info header = { 0 };
614 header.instance = instance_id;
615 header.msg_type = PLDM_REQUEST;
616 header.pldm_type = PLDM_BIOS;
617 header.command = PLDM_SET_BIOS_TABLE;
618
619 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
620 if (rc != PLDM_SUCCESS) {
621 return rc;
622 }
623
624 struct pldm_set_bios_table_req *request =
625 (struct pldm_set_bios_table_req *)msg->payload;
626 request->transfer_handle = htole32(transfer_handle);
627 request->transfer_flag = transfer_flag;
628 request->table_type = table_type;
629 memcpy(request->table_data, table_data, table_length);
630
631 return PLDM_SUCCESS;
632 }
633
634 LIBPLDM_ABI_STABLE
decode_set_bios_table_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle)635 int decode_set_bios_table_resp(const struct pldm_msg *msg,
636 size_t payload_length, uint8_t *completion_code,
637 uint32_t *next_transfer_handle)
638 {
639 if (msg == NULL || completion_code == NULL ||
640 next_transfer_handle == NULL) {
641 return PLDM_ERROR_INVALID_DATA;
642 }
643
644 *completion_code = msg->payload[0];
645 if (PLDM_SUCCESS != *completion_code) {
646 return PLDM_SUCCESS;
647 }
648
649 if (payload_length != PLDM_SET_BIOS_TABLE_RESP_BYTES) {
650 return PLDM_ERROR_INVALID_LENGTH;
651 }
652
653 struct pldm_set_bios_table_resp *response =
654 (struct pldm_set_bios_table_resp *)msg->payload;
655
656 *next_transfer_handle = le32toh(response->next_transfer_handle);
657
658 return PLDM_SUCCESS;
659 }
660
661 LIBPLDM_ABI_STABLE
encode_set_bios_table_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,struct pldm_msg * msg)662 int encode_set_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
663 uint32_t next_transfer_handle,
664 struct pldm_msg *msg)
665 {
666 if (msg == NULL) {
667 return PLDM_ERROR_INVALID_DATA;
668 }
669
670 struct pldm_header_info header = { 0 };
671 header.instance = instance_id;
672 header.msg_type = PLDM_RESPONSE;
673 header.pldm_type = PLDM_BIOS;
674 header.command = PLDM_SET_BIOS_TABLE;
675
676 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
677 if (rc != PLDM_SUCCESS) {
678 return rc;
679 }
680
681 struct pldm_set_bios_table_resp *response =
682 (struct pldm_set_bios_table_resp *)msg->payload;
683 response->completion_code = completion_code;
684 response->next_transfer_handle = htole32(next_transfer_handle);
685
686 return PLDM_SUCCESS;
687 }
688
689 LIBPLDM_ABI_STABLE
decode_set_bios_table_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_flag,uint8_t * table_type,struct variable_field * table)690 int decode_set_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
691 uint32_t *transfer_handle, uint8_t *transfer_flag,
692 uint8_t *table_type, struct variable_field *table)
693 {
694 if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
695 table_type == NULL || table == NULL) {
696 return PLDM_ERROR_INVALID_DATA;
697 }
698
699 if (payload_length < PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES) {
700 return PLDM_ERROR_INVALID_LENGTH;
701 }
702
703 struct pldm_set_bios_table_req *request =
704 (struct pldm_set_bios_table_req *)msg->payload;
705 *transfer_handle = le32toh(request->transfer_handle);
706 *transfer_flag = request->transfer_flag;
707 *table_type = request->table_type;
708 table->length = payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES;
709 table->ptr = request->table_data;
710
711 return PLDM_SUCCESS;
712 }
713