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