xref: /openbmc/libpldm/src/dsp/bios.c (revision bc19d9c9032edd75251e6fdb7b60145735328430)
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