1 /* 2 * Copyright (c) 2020-2022, Intel Corporation. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <lib/mmio.h> 9 10 #include "socfpga_fcs.h" 11 #include "socfpga_mailbox.h" 12 #include "socfpga_sip_svc.h" 13 14 bool is_size_4_bytes_aligned(uint32_t size) 15 { 16 if ((size % MBOX_WORD_BYTE) != 0U) { 17 return false; 18 } else { 19 return true; 20 } 21 } 22 23 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 24 uint32_t *mbox_error) 25 { 26 int status; 27 unsigned int i; 28 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 29 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 30 31 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 32 return INTEL_SIP_SMC_STATUS_REJECTED; 33 } 34 35 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 36 CMD_CASUAL, random_data, &resp_len); 37 38 if (status < 0) { 39 *mbox_error = -status; 40 return INTEL_SIP_SMC_STATUS_ERROR; 41 } 42 43 if (resp_len != FCS_RANDOM_WORD_SIZE) { 44 *mbox_error = GENERIC_RESPONSE_ERROR; 45 return INTEL_SIP_SMC_STATUS_ERROR; 46 } 47 48 *ret_size = FCS_RANDOM_BYTE_SIZE; 49 50 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 51 mmio_write_32(addr, random_data[i]); 52 addr += MBOX_WORD_BYTE; 53 } 54 55 flush_dcache_range(addr - *ret_size, *ret_size); 56 57 return INTEL_SIP_SMC_STATUS_OK; 58 } 59 60 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 61 uint32_t size, uint32_t *send_id) 62 { 63 int status; 64 uint32_t payload_size; 65 uint32_t crypto_header; 66 67 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 68 MBOX_WORD_BYTE) || size == 0U) { 69 return INTEL_SIP_SMC_STATUS_REJECTED; 70 } 71 72 if (!is_size_4_bytes_aligned(size)) { 73 return INTEL_SIP_SMC_STATUS_REJECTED; 74 } 75 76 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 77 FCS_CS_FIELD_FLAG_OFFSET; 78 79 fcs_rng_payload payload = { 80 session_id, 81 context_id, 82 crypto_header, 83 size 84 }; 85 86 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 87 88 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 89 (uint32_t *) &payload, payload_size, 90 CMD_INDIRECT); 91 92 if (status < 0) { 93 return INTEL_SIP_SMC_STATUS_ERROR; 94 } 95 96 return INTEL_SIP_SMC_STATUS_OK; 97 } 98 99 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, 100 uint32_t *send_id) 101 { 102 int status; 103 104 if (!is_address_in_ddr_range(addr, size)) { 105 return INTEL_SIP_SMC_STATUS_REJECTED; 106 } 107 108 if (!is_size_4_bytes_aligned(size)) { 109 return INTEL_SIP_SMC_STATUS_REJECTED; 110 } 111 112 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 113 (uint32_t *)addr, size / MBOX_WORD_BYTE, 114 CMD_DIRECT); 115 116 flush_dcache_range(addr, size); 117 118 if (status < 0) { 119 return INTEL_SIP_SMC_STATUS_ERROR; 120 } 121 122 return INTEL_SIP_SMC_STATUS_OK; 123 } 124 125 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 126 { 127 int status; 128 129 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 130 NULL, 0U, CMD_DIRECT); 131 132 if (status < 0) { 133 return INTEL_SIP_SMC_STATUS_ERROR; 134 } 135 136 return INTEL_SIP_SMC_STATUS_OK; 137 } 138 139 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 140 uint32_t test_bit, uint32_t *mbox_error) 141 { 142 int status; 143 uint32_t first_word; 144 uint32_t payload_size; 145 146 if ((test_bit != MBOX_TEST_BIT) && 147 (test_bit != 0)) { 148 return INTEL_SIP_SMC_STATUS_REJECTED; 149 } 150 151 if ((counter_type < FCS_BIG_CNTR_SEL) || 152 (counter_type > FCS_SVN_CNTR_3_SEL)) { 153 return INTEL_SIP_SMC_STATUS_REJECTED; 154 } 155 156 if ((counter_type == FCS_BIG_CNTR_SEL) && 157 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 158 return INTEL_SIP_SMC_STATUS_REJECTED; 159 } 160 161 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 162 (counter_type <= FCS_SVN_CNTR_3_SEL) && 163 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 164 return INTEL_SIP_SMC_STATUS_REJECTED; 165 } 166 167 first_word = test_bit | counter_type; 168 fcs_cntr_set_preauth_payload payload = { 169 first_word, 170 counter_value 171 }; 172 173 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 174 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 175 (uint32_t *) &payload, payload_size, 176 CMD_CASUAL, NULL, NULL); 177 178 if (status < 0) { 179 *mbox_error = -status; 180 return INTEL_SIP_SMC_STATUS_ERROR; 181 } 182 183 return INTEL_SIP_SMC_STATUS_OK; 184 } 185 186 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 187 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 188 { 189 int status; 190 uint32_t load_size; 191 192 fcs_encrypt_payload payload = { 193 FCS_ENCRYPTION_DATA_0, 194 src_addr, 195 src_size, 196 dst_addr, 197 dst_size }; 198 load_size = sizeof(payload) / MBOX_WORD_BYTE; 199 200 if (!is_address_in_ddr_range(src_addr, src_size) || 201 !is_address_in_ddr_range(dst_addr, dst_size)) { 202 return INTEL_SIP_SMC_STATUS_REJECTED; 203 } 204 205 if (!is_size_4_bytes_aligned(src_size)) { 206 return INTEL_SIP_SMC_STATUS_REJECTED; 207 } 208 209 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 210 (uint32_t *) &payload, load_size, 211 CMD_INDIRECT); 212 inv_dcache_range(dst_addr, dst_size); 213 214 if (status < 0) { 215 return INTEL_SIP_SMC_STATUS_REJECTED; 216 } 217 218 return INTEL_SIP_SMC_STATUS_OK; 219 } 220 221 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 222 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 223 { 224 int status; 225 uint32_t load_size; 226 uintptr_t id_offset; 227 228 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 229 fcs_decrypt_payload payload = { 230 FCS_DECRYPTION_DATA_0, 231 {mmio_read_32(id_offset), 232 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 233 src_addr, 234 src_size, 235 dst_addr, 236 dst_size }; 237 load_size = sizeof(payload) / MBOX_WORD_BYTE; 238 239 if (!is_address_in_ddr_range(src_addr, src_size) || 240 !is_address_in_ddr_range(dst_addr, dst_size)) { 241 return INTEL_SIP_SMC_STATUS_REJECTED; 242 } 243 244 if (!is_size_4_bytes_aligned(src_size)) { 245 return INTEL_SIP_SMC_STATUS_REJECTED; 246 } 247 248 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 249 (uint32_t *) &payload, load_size, 250 CMD_INDIRECT); 251 inv_dcache_range(dst_addr, dst_size); 252 253 if (status < 0) { 254 return INTEL_SIP_SMC_STATUS_REJECTED; 255 } 256 257 return INTEL_SIP_SMC_STATUS_OK; 258 } 259 260 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 261 uint32_t *mbox_error) 262 { 263 int status; 264 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 265 266 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 267 return INTEL_SIP_SMC_STATUS_REJECTED; 268 } 269 270 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 271 CMD_CASUAL, (uint32_t *) addr, &resp_len); 272 273 if (status < 0) { 274 *mbox_error = -status; 275 return INTEL_SIP_SMC_STATUS_ERROR; 276 } 277 278 if (resp_len != FCS_SHA384_WORD_SIZE) { 279 *mbox_error = GENERIC_RESPONSE_ERROR; 280 return INTEL_SIP_SMC_STATUS_ERROR; 281 } 282 283 *ret_size = FCS_SHA384_BYTE_SIZE; 284 285 flush_dcache_range(addr, *ret_size); 286 287 return INTEL_SIP_SMC_STATUS_OK; 288 } 289 290 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 291 { 292 int status; 293 294 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 295 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 296 return INTEL_SIP_SMC_STATUS_REJECTED; 297 } 298 299 psgsigma_teardown_msg message = { 300 RESERVED_AS_ZERO, 301 PSGSIGMA_TEARDOWN_MAGIC, 302 session_id 303 }; 304 305 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 306 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 307 CMD_CASUAL, NULL, NULL); 308 309 if (status < 0) { 310 *mbox_error = -status; 311 return INTEL_SIP_SMC_STATUS_ERROR; 312 } 313 314 return INTEL_SIP_SMC_STATUS_OK; 315 } 316 317 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 318 { 319 int status; 320 uint32_t load_size; 321 uint32_t chip_id[2]; 322 323 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 324 325 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 326 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 327 328 if (status < 0) { 329 *mbox_error = -status; 330 return INTEL_SIP_SMC_STATUS_ERROR; 331 } 332 333 *id_low = chip_id[0]; 334 *id_high = chip_id[1]; 335 336 return INTEL_SIP_SMC_STATUS_OK; 337 } 338 339 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 340 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 341 { 342 int status; 343 uint32_t send_size = src_size / MBOX_WORD_BYTE; 344 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 345 346 347 if (!is_address_in_ddr_range(src_addr, src_size) || 348 !is_address_in_ddr_range(dst_addr, *dst_size)) { 349 return INTEL_SIP_SMC_STATUS_REJECTED; 350 } 351 352 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 353 (uint32_t *) src_addr, send_size, CMD_CASUAL, 354 (uint32_t *) dst_addr, &ret_size); 355 356 if (status < 0) { 357 *mbox_error = -status; 358 return INTEL_SIP_SMC_STATUS_ERROR; 359 } 360 361 *dst_size = ret_size * MBOX_WORD_BYTE; 362 flush_dcache_range(dst_addr, *dst_size); 363 364 return INTEL_SIP_SMC_STATUS_OK; 365 } 366 367 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 368 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 369 { 370 int status; 371 uint32_t send_size = src_size / MBOX_WORD_BYTE; 372 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 373 374 if (!is_address_in_ddr_range(src_addr, src_size) || 375 !is_address_in_ddr_range(dst_addr, *dst_size)) { 376 return INTEL_SIP_SMC_STATUS_REJECTED; 377 } 378 379 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 380 (uint32_t *) src_addr, send_size, CMD_CASUAL, 381 (uint32_t *) dst_addr, &ret_size); 382 383 if (status < 0) { 384 *mbox_error = -status; 385 return INTEL_SIP_SMC_STATUS_ERROR; 386 } 387 388 *dst_size = ret_size * MBOX_WORD_BYTE; 389 flush_dcache_range(dst_addr, *dst_size); 390 391 return INTEL_SIP_SMC_STATUS_OK; 392 } 393 394 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 395 uint32_t *dst_size, uint32_t *mbox_error) 396 { 397 int status; 398 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 399 400 if (mbox_error == NULL) { 401 return INTEL_SIP_SMC_STATUS_REJECTED; 402 } 403 404 if (cert_request < FCS_ALIAS_CERT || 405 cert_request > 406 (FCS_ALIAS_CERT | 407 FCS_DEV_ID_SELF_SIGN_CERT | 408 FCS_DEV_ID_ENROLL_CERT | 409 FCS_ENROLL_SELF_SIGN_CERT | 410 FCS_PLAT_KEY_CERT)) { 411 return INTEL_SIP_SMC_STATUS_REJECTED; 412 } 413 414 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 415 return INTEL_SIP_SMC_STATUS_REJECTED; 416 } 417 418 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 419 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 420 (uint32_t *) dst_addr, &ret_size); 421 422 if (status < 0) { 423 *mbox_error = -status; 424 return INTEL_SIP_SMC_STATUS_ERROR; 425 } 426 427 *dst_size = ret_size * MBOX_WORD_BYTE; 428 flush_dcache_range(dst_addr, *dst_size); 429 430 return INTEL_SIP_SMC_STATUS_OK; 431 } 432 433 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 434 uint32_t *mbox_error) 435 { 436 int status; 437 438 if (mbox_error == NULL) { 439 return INTEL_SIP_SMC_STATUS_REJECTED; 440 } 441 442 if (cert_request < FCS_ALIAS_CERT || 443 cert_request > 444 (FCS_ALIAS_CERT | 445 FCS_DEV_ID_SELF_SIGN_CERT | 446 FCS_DEV_ID_ENROLL_CERT | 447 FCS_ENROLL_SELF_SIGN_CERT | 448 FCS_PLAT_KEY_CERT)) { 449 return INTEL_SIP_SMC_STATUS_REJECTED; 450 } 451 452 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 453 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 454 NULL, NULL); 455 456 if (status < 0) { 457 *mbox_error = -status; 458 return INTEL_SIP_SMC_STATUS_ERROR; 459 } 460 461 return INTEL_SIP_SMC_STATUS_OK; 462 } 463 464 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 465 uint32_t *mbox_error) 466 { 467 int status; 468 uint32_t resp_len = 1U; 469 470 if ((session_id == NULL) || (mbox_error == NULL)) { 471 return INTEL_SIP_SMC_STATUS_REJECTED; 472 } 473 474 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 475 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 476 477 if (status < 0) { 478 *mbox_error = -status; 479 return INTEL_SIP_SMC_STATUS_ERROR; 480 } 481 482 return INTEL_SIP_SMC_STATUS_OK; 483 } 484 485 int intel_fcs_close_crypto_service_session(uint32_t session_id, 486 uint32_t *mbox_error) 487 { 488 int status; 489 490 if (mbox_error == NULL) { 491 return INTEL_SIP_SMC_STATUS_REJECTED; 492 } 493 494 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 495 &session_id, 1U, CMD_CASUAL, NULL, NULL); 496 497 if (status < 0) { 498 *mbox_error = -status; 499 return INTEL_SIP_SMC_STATUS_ERROR; 500 } 501 502 return INTEL_SIP_SMC_STATUS_OK; 503 } 504 505 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 506 uint32_t *send_id) 507 { 508 int status; 509 510 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 511 MBOX_WORD_BYTE)) { 512 return INTEL_SIP_SMC_STATUS_REJECTED; 513 } 514 515 if (!is_address_in_ddr_range(src_addr, src_size)) { 516 return INTEL_SIP_SMC_STATUS_REJECTED; 517 } 518 519 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 520 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 521 CMD_INDIRECT); 522 523 if (status < 0) { 524 return INTEL_SIP_SMC_STATUS_ERROR; 525 } 526 527 return INTEL_SIP_SMC_STATUS_OK; 528 } 529 530 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 531 uint64_t dst_addr, uint32_t *dst_size, 532 uint32_t *mbox_error) 533 { 534 int status; 535 uint32_t i; 536 uint32_t payload_size; 537 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 538 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 539 uint32_t op_status = 0U; 540 541 if ((dst_size == NULL) || (mbox_error == NULL)) { 542 return INTEL_SIP_SMC_STATUS_REJECTED; 543 } 544 545 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 546 return INTEL_SIP_SMC_STATUS_REJECTED; 547 } 548 549 fcs_cs_key_payload payload = { 550 session_id, 551 RESERVED_AS_ZERO, 552 RESERVED_AS_ZERO, 553 key_id 554 }; 555 556 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 557 558 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 559 (uint32_t *) &payload, payload_size, 560 CMD_CASUAL, resp_data, &resp_len); 561 562 if (resp_len > 0) { 563 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 564 } 565 566 if (status < 0) { 567 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 568 return INTEL_SIP_SMC_STATUS_ERROR; 569 } 570 571 if (resp_len > 1) { 572 573 /* Export key object is start at second response data */ 574 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 575 576 for (i = 1U; i < resp_len; i++) { 577 mmio_write_32(dst_addr, resp_data[i]); 578 dst_addr += MBOX_WORD_BYTE; 579 } 580 581 flush_dcache_range(dst_addr - *dst_size, *dst_size); 582 583 } else { 584 585 /* Unexpected response, missing key object in response */ 586 *mbox_error = MBOX_RET_ERROR; 587 return INTEL_SIP_SMC_STATUS_ERROR; 588 } 589 590 return INTEL_SIP_SMC_STATUS_OK; 591 } 592 593 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 594 uint32_t *mbox_error) 595 { 596 int status; 597 uint32_t payload_size; 598 uint32_t resp_len = 1U; 599 uint32_t resp_data = 0U; 600 uint32_t op_status = 0U; 601 602 if (mbox_error == NULL) { 603 return INTEL_SIP_SMC_STATUS_REJECTED; 604 } 605 606 fcs_cs_key_payload payload = { 607 session_id, 608 RESERVED_AS_ZERO, 609 RESERVED_AS_ZERO, 610 key_id 611 }; 612 613 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 614 615 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 616 (uint32_t *) &payload, payload_size, 617 CMD_CASUAL, &resp_data, &resp_len); 618 619 if (resp_len > 0) { 620 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 621 } 622 623 if (status < 0) { 624 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 625 return INTEL_SIP_SMC_STATUS_ERROR; 626 } 627 628 return INTEL_SIP_SMC_STATUS_OK; 629 } 630 631 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 632 uint64_t dst_addr, uint32_t *dst_size, 633 uint32_t *mbox_error) 634 { 635 int status; 636 uint32_t payload_size; 637 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 638 uint32_t op_status = 0U; 639 640 if ((dst_size == NULL) || (mbox_error == NULL)) { 641 return INTEL_SIP_SMC_STATUS_REJECTED; 642 } 643 644 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 645 return INTEL_SIP_SMC_STATUS_REJECTED; 646 } 647 648 fcs_cs_key_payload payload = { 649 session_id, 650 RESERVED_AS_ZERO, 651 RESERVED_AS_ZERO, 652 key_id 653 }; 654 655 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 656 657 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 658 (uint32_t *) &payload, payload_size, 659 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 660 661 if (resp_len > 0) { 662 op_status = mmio_read_32(dst_addr) & 663 FCS_CS_KEY_RESP_STATUS_MASK; 664 } 665 666 if (status < 0) { 667 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 668 return INTEL_SIP_SMC_STATUS_ERROR; 669 } 670 671 *dst_size = resp_len * MBOX_WORD_BYTE; 672 flush_dcache_range(dst_addr, *dst_size); 673 674 return INTEL_SIP_SMC_STATUS_OK; 675 } 676