xref: /openbmc/libpldm/src/dsp/bios.c (revision 36324f6b)
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
encode_get_date_time_req(uint8_t instance_id,struct pldm_msg * msg)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
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)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
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)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
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)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
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)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
encode_set_date_time_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg,size_t payload_length)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
decode_set_date_time_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)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_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)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
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)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
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)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
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)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
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)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
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)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
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)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_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)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
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)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 
478 	if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
479 		return PLDM_ERROR_INVALID_LENGTH;
480 	}
481 
482 	if (payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES <
483 	    attribute_length) {
484 		return PLDM_ERROR_INVALID_LENGTH;
485 	}
486 
487 	struct pldm_header_info header = { 0 };
488 	header.instance = instance_id;
489 	header.msg_type = PLDM_REQUEST;
490 	header.pldm_type = PLDM_BIOS;
491 	header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
492 
493 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
494 	if (rc != PLDM_SUCCESS) {
495 		return rc;
496 	}
497 
498 	struct pldm_set_bios_attribute_current_value_req *request =
499 		(struct pldm_set_bios_attribute_current_value_req *)msg->payload;
500 	request->transfer_handle = htole32(transfer_handle);
501 	request->transfer_flag = transfer_flag;
502 	memcpy(request->attribute_data, attribute_data, attribute_length);
503 
504 	return PLDM_SUCCESS;
505 }
506 
507 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)508 int decode_set_bios_attribute_current_value_resp(const struct pldm_msg *msg,
509 						 size_t payload_length,
510 						 uint8_t *completion_code,
511 						 uint32_t *next_transfer_handle)
512 {
513 	if (msg == NULL || completion_code == NULL ||
514 	    next_transfer_handle == NULL) {
515 		return PLDM_ERROR_INVALID_DATA;
516 	}
517 
518 	*completion_code = msg->payload[0];
519 	if (PLDM_SUCCESS != *completion_code) {
520 		return PLDM_SUCCESS;
521 	}
522 
523 	if (payload_length != PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES) {
524 		return PLDM_ERROR_INVALID_LENGTH;
525 	}
526 
527 	struct pldm_set_bios_attribute_current_value_resp *response =
528 		(struct pldm_set_bios_attribute_current_value_resp *)
529 			msg->payload;
530 
531 	*next_transfer_handle = le32toh(response->next_transfer_handle);
532 
533 	return PLDM_SUCCESS;
534 }
535 
536 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)537 int decode_set_bios_attribute_current_value_req(
538 	const struct pldm_msg *msg, size_t payload_length,
539 	uint32_t *transfer_handle, uint8_t *transfer_flag,
540 	struct variable_field *attribute)
541 {
542 	if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
543 	    attribute == NULL) {
544 		return PLDM_ERROR_INVALID_DATA;
545 	}
546 	if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
547 		return PLDM_ERROR_INVALID_LENGTH;
548 	}
549 
550 	struct pldm_set_bios_attribute_current_value_req *request =
551 		(struct pldm_set_bios_attribute_current_value_req *)msg->payload;
552 	*transfer_handle = le32toh(request->transfer_handle);
553 	*transfer_flag = request->transfer_flag;
554 	attribute->length =
555 		payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES;
556 	attribute->ptr = request->attribute_data;
557 	return PLDM_SUCCESS;
558 }
559 
560 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)561 int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
562 						 uint8_t completion_code,
563 						 uint32_t next_transfer_handle,
564 						 struct pldm_msg *msg)
565 {
566 	if (msg == NULL) {
567 		return PLDM_ERROR_INVALID_DATA;
568 	}
569 	struct pldm_header_info header = { 0 };
570 	header.instance = instance_id;
571 	header.msg_type = PLDM_RESPONSE;
572 	header.pldm_type = PLDM_BIOS;
573 	header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
574 
575 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
576 	if (rc != PLDM_SUCCESS) {
577 		return rc;
578 	}
579 
580 	struct pldm_set_bios_attribute_current_value_resp *response =
581 		(struct pldm_set_bios_attribute_current_value_resp *)
582 			msg->payload;
583 	response->completion_code = completion_code;
584 	response->next_transfer_handle = htole32(next_transfer_handle);
585 
586 	return PLDM_SUCCESS;
587 }
588 
589 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)590 int encode_set_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
591 			      uint8_t transfer_flag, uint8_t table_type,
592 			      const uint8_t *table_data, size_t table_length,
593 			      struct pldm_msg *msg, size_t payload_length)
594 {
595 	if (msg == NULL || table_data == NULL) {
596 		return PLDM_ERROR_INVALID_DATA;
597 	}
598 
599 	if (payload_length < PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES) {
600 		return PLDM_ERROR_INVALID_LENGTH;
601 	}
602 
603 	if (payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES < table_length) {
604 		return PLDM_ERROR_INVALID_LENGTH;
605 	}
606 
607 	if (payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES > table_length) {
608 		return PLDM_ERROR_INVALID_LENGTH;
609 	}
610 
611 	struct pldm_header_info header = { 0 };
612 	header.instance = instance_id;
613 	header.msg_type = PLDM_REQUEST;
614 	header.pldm_type = PLDM_BIOS;
615 	header.command = PLDM_SET_BIOS_TABLE;
616 
617 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
618 	if (rc != PLDM_SUCCESS) {
619 		return rc;
620 	}
621 
622 	struct pldm_set_bios_table_req *request =
623 		(struct pldm_set_bios_table_req *)msg->payload;
624 	request->transfer_handle = htole32(transfer_handle);
625 	request->transfer_flag = transfer_flag;
626 	request->table_type = table_type;
627 	memcpy(request->table_data, table_data, table_length);
628 
629 	return PLDM_SUCCESS;
630 }
631 
632 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)633 int decode_set_bios_table_resp(const struct pldm_msg *msg,
634 			       size_t payload_length, uint8_t *completion_code,
635 			       uint32_t *next_transfer_handle)
636 {
637 	if (msg == NULL || completion_code == NULL ||
638 	    next_transfer_handle == NULL) {
639 		return PLDM_ERROR_INVALID_DATA;
640 	}
641 
642 	*completion_code = msg->payload[0];
643 	if (PLDM_SUCCESS != *completion_code) {
644 		return PLDM_SUCCESS;
645 	}
646 
647 	if (payload_length != PLDM_SET_BIOS_TABLE_RESP_BYTES) {
648 		return PLDM_ERROR_INVALID_LENGTH;
649 	}
650 
651 	struct pldm_set_bios_table_resp *response =
652 		(struct pldm_set_bios_table_resp *)msg->payload;
653 
654 	*next_transfer_handle = le32toh(response->next_transfer_handle);
655 
656 	return PLDM_SUCCESS;
657 }
658 
659 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)660 int encode_set_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
661 			       uint32_t next_transfer_handle,
662 			       struct pldm_msg *msg)
663 {
664 	if (msg == NULL) {
665 		return PLDM_ERROR_INVALID_DATA;
666 	}
667 
668 	struct pldm_header_info header = { 0 };
669 	header.instance = instance_id;
670 	header.msg_type = PLDM_RESPONSE;
671 	header.pldm_type = PLDM_BIOS;
672 	header.command = PLDM_SET_BIOS_TABLE;
673 
674 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
675 	if (rc != PLDM_SUCCESS) {
676 		return rc;
677 	}
678 
679 	struct pldm_set_bios_table_resp *response =
680 		(struct pldm_set_bios_table_resp *)msg->payload;
681 	response->completion_code = completion_code;
682 	response->next_transfer_handle = htole32(next_transfer_handle);
683 
684 	return PLDM_SUCCESS;
685 }
686 
687 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)688 int decode_set_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
689 			      uint32_t *transfer_handle, uint8_t *transfer_flag,
690 			      uint8_t *table_type, struct variable_field *table)
691 {
692 	if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
693 	    table_type == NULL || table == NULL) {
694 		return PLDM_ERROR_INVALID_DATA;
695 	}
696 
697 	if (payload_length < PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES) {
698 		return PLDM_ERROR_INVALID_LENGTH;
699 	}
700 
701 	struct pldm_set_bios_table_req *request =
702 		(struct pldm_set_bios_table_req *)msg->payload;
703 	*transfer_handle = le32toh(request->transfer_handle);
704 	*transfer_flag = request->transfer_flag;
705 	*table_type = request->table_type;
706 	table->length = payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES;
707 	table->ptr = request->table_data;
708 
709 	return PLDM_SUCCESS;
710 }
711