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 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 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 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 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 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 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 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 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