1 /* 2 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <arch_helpers.h> 11 #include <bl31/bl31.h> 12 #include <bl31/ehf.h> 13 #include <common/debug.h> 14 #include <common/fdt_wrappers.h> 15 #include <common/runtime_svc.h> 16 #include <lib/el3_runtime/context_mgmt.h> 17 #include <lib/smccc.h> 18 #include <lib/utils.h> 19 #include <lib/xlat_tables/xlat_tables_v2.h> 20 #include <libfdt.h> 21 #include <plat/common/platform.h> 22 #include <services/el3_spmc_logical_sp.h> 23 #include <services/ffa_svc.h> 24 #include <services/spmc_svc.h> 25 #include <services/spmd_svc.h> 26 #include "spmc.h" 27 28 #include <platform_def.h> 29 30 /* 31 * Allocate a secure partition descriptor to describe each SP in the system that 32 * does not reside at EL3. 33 */ 34 static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT]; 35 36 /* 37 * Allocate an NS endpoint descriptor to describe each VM and the Hypervisor in 38 * the system that interacts with a SP. It is used to track the Hypervisor 39 * buffer pair, version and ID for now. It could be extended to track VM 40 * properties when the SPMC supports indirect messaging. 41 */ 42 static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT]; 43 44 /* 45 * Helper function to obtain the array storing the EL3 46 * Logical Partition descriptors. 47 */ 48 struct el3_lp_desc *get_el3_lp_array(void) 49 { 50 return (struct el3_lp_desc *) EL3_LP_DESCS_START; 51 } 52 53 /* 54 * Helper function to obtain the descriptor of the last SP to whom control was 55 * handed to on this physical cpu. Currently, we assume there is only one SP. 56 * TODO: Expand to track multiple partitions when required. 57 */ 58 struct secure_partition_desc *spmc_get_current_sp_ctx(void) 59 { 60 return &(sp_desc[ACTIVE_SP_DESC_INDEX]); 61 } 62 63 /* 64 * Helper function to obtain the execution context of an SP on the 65 * current physical cpu. 66 */ 67 struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp) 68 { 69 return &(sp->ec[get_ec_index(sp)]); 70 } 71 72 /* Helper function to get pointer to SP context from its ID. */ 73 struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id) 74 { 75 /* Check for SWd Partitions. */ 76 for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { 77 if (sp_desc[i].sp_id == id) { 78 return &(sp_desc[i]); 79 } 80 } 81 return NULL; 82 } 83 84 /****************************************************************************** 85 * This function returns to the place where spmc_sp_synchronous_entry() was 86 * called originally. 87 ******************************************************************************/ 88 __dead2 void spmc_sp_synchronous_exit(struct sp_exec_ctx *ec, uint64_t rc) 89 { 90 /* 91 * The SPM must have initiated the original request through a 92 * synchronous entry into the secure partition. Jump back to the 93 * original C runtime context with the value of rc in x0; 94 */ 95 spm_secure_partition_exit(ec->c_rt_ctx, rc); 96 97 panic(); 98 } 99 100 /******************************************************************************* 101 * Return FFA_ERROR with specified error code. 102 ******************************************************************************/ 103 uint64_t spmc_ffa_error_return(void *handle, int error_code) 104 { 105 SMC_RET8(handle, FFA_ERROR, 106 FFA_TARGET_INFO_MBZ, error_code, 107 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 108 FFA_PARAM_MBZ, FFA_PARAM_MBZ); 109 } 110 111 /****************************************************************************** 112 * Helper function to validate a secure partition ID to ensure it does not 113 * conflict with any other FF-A component and follows the convention to 114 * indicate it resides within the secure world. 115 ******************************************************************************/ 116 bool is_ffa_secure_id_valid(uint16_t partition_id) 117 { 118 struct el3_lp_desc *el3_lp_descs = get_el3_lp_array(); 119 120 /* Ensure the ID is not the invalid partition ID. */ 121 if (partition_id == INV_SP_ID) { 122 return false; 123 } 124 125 /* Ensure the ID is not the SPMD ID. */ 126 if (partition_id == SPMD_DIRECT_MSG_ENDPOINT_ID) { 127 return false; 128 } 129 130 /* 131 * Ensure the ID follows the convention to indicate it resides 132 * in the secure world. 133 */ 134 if (!ffa_is_secure_world_id(partition_id)) { 135 return false; 136 } 137 138 /* Ensure we don't conflict with the SPMC partition ID. */ 139 if (partition_id == FFA_SPMC_ID) { 140 return false; 141 } 142 143 /* Ensure we do not already have an SP context with this ID. */ 144 if (spmc_get_sp_ctx(partition_id)) { 145 return false; 146 } 147 148 /* Ensure we don't clash with any Logical SP's. */ 149 for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) { 150 if (el3_lp_descs[i].sp_id == partition_id) { 151 return false; 152 } 153 } 154 155 return true; 156 } 157 158 /******************************************************************************* 159 * This function either forwards the request to the other world or returns 160 * with an ERET depending on the source of the call. 161 * We can assume that the destination is for an entity at a lower exception 162 * level as any messages destined for a logical SP resident in EL3 will have 163 * already been taken care of by the SPMC before entering this function. 164 ******************************************************************************/ 165 static uint64_t spmc_smc_return(uint32_t smc_fid, 166 bool secure_origin, 167 uint64_t x1, 168 uint64_t x2, 169 uint64_t x3, 170 uint64_t x4, 171 void *handle, 172 void *cookie, 173 uint64_t flags, 174 uint16_t dst_id) 175 { 176 /* If the destination is in the normal world always go via the SPMD. */ 177 if (ffa_is_normal_world_id(dst_id)) { 178 return spmd_smc_handler(smc_fid, x1, x2, x3, x4, 179 cookie, handle, flags); 180 } 181 /* 182 * If the caller is secure and we want to return to the secure world, 183 * ERET directly. 184 */ 185 else if (secure_origin && ffa_is_secure_world_id(dst_id)) { 186 SMC_RET5(handle, smc_fid, x1, x2, x3, x4); 187 } 188 /* If we originated in the normal world then switch contexts. */ 189 else if (!secure_origin && ffa_is_secure_world_id(dst_id)) { 190 return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, 191 x3, x4, handle); 192 } else { 193 /* Unknown State. */ 194 panic(); 195 } 196 197 /* Shouldn't be Reached. */ 198 return 0; 199 } 200 201 /******************************************************************************* 202 * FF-A ABI Handlers. 203 ******************************************************************************/ 204 205 /******************************************************************************* 206 * Helper function to validate arg2 as part of a direct message. 207 ******************************************************************************/ 208 static inline bool direct_msg_validate_arg2(uint64_t x2) 209 { 210 /* 211 * We currently only support partition messages, therefore ensure x2 is 212 * not set. 213 */ 214 if (x2 != (uint64_t) 0) { 215 VERBOSE("Arg2 MBZ for partition messages (0x%lx).\n", x2); 216 return false; 217 } 218 return true; 219 } 220 221 /******************************************************************************* 222 * Handle direct request messages and route to the appropriate destination. 223 ******************************************************************************/ 224 static uint64_t direct_req_smc_handler(uint32_t smc_fid, 225 bool secure_origin, 226 uint64_t x1, 227 uint64_t x2, 228 uint64_t x3, 229 uint64_t x4, 230 void *cookie, 231 void *handle, 232 uint64_t flags) 233 { 234 uint16_t dst_id = ffa_endpoint_destination(x1); 235 struct el3_lp_desc *el3_lp_descs; 236 struct secure_partition_desc *sp; 237 unsigned int idx; 238 239 /* Check if arg2 has been populated correctly based on message type. */ 240 if (!direct_msg_validate_arg2(x2)) { 241 return spmc_ffa_error_return(handle, 242 FFA_ERROR_INVALID_PARAMETER); 243 } 244 245 el3_lp_descs = get_el3_lp_array(); 246 247 /* Check if the request is destined for a Logical Partition. */ 248 for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) { 249 if (el3_lp_descs[i].sp_id == dst_id) { 250 return el3_lp_descs[i].direct_req( 251 smc_fid, secure_origin, x1, x2, x3, x4, 252 cookie, handle, flags); 253 } 254 } 255 256 /* 257 * If the request was not targeted to a LSP and from the secure world 258 * then it is invalid since a SP cannot call into the Normal world and 259 * there is no other SP to call into. If there are other SPs in future 260 * then the partition runtime model would need to be validated as well. 261 */ 262 if (secure_origin) { 263 VERBOSE("Direct request not supported to the Normal World.\n"); 264 return spmc_ffa_error_return(handle, 265 FFA_ERROR_INVALID_PARAMETER); 266 } 267 268 /* Check if the SP ID is valid. */ 269 sp = spmc_get_sp_ctx(dst_id); 270 if (sp == NULL) { 271 VERBOSE("Direct request to unknown partition ID (0x%x).\n", 272 dst_id); 273 return spmc_ffa_error_return(handle, 274 FFA_ERROR_INVALID_PARAMETER); 275 } 276 277 /* 278 * Check that the target execution context is in a waiting state before 279 * forwarding the direct request to it. 280 */ 281 idx = get_ec_index(sp); 282 if (sp->ec[idx].rt_state != RT_STATE_WAITING) { 283 VERBOSE("SP context on core%u is not waiting (%u).\n", 284 idx, sp->ec[idx].rt_model); 285 return spmc_ffa_error_return(handle, FFA_ERROR_BUSY); 286 } 287 288 /* 289 * Everything checks out so forward the request to the SP after updating 290 * its state and runtime model. 291 */ 292 sp->ec[idx].rt_state = RT_STATE_RUNNING; 293 sp->ec[idx].rt_model = RT_MODEL_DIR_REQ; 294 return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4, 295 handle, cookie, flags, dst_id); 296 } 297 298 /******************************************************************************* 299 * Handle direct response messages and route to the appropriate destination. 300 ******************************************************************************/ 301 static uint64_t direct_resp_smc_handler(uint32_t smc_fid, 302 bool secure_origin, 303 uint64_t x1, 304 uint64_t x2, 305 uint64_t x3, 306 uint64_t x4, 307 void *cookie, 308 void *handle, 309 uint64_t flags) 310 { 311 uint16_t dst_id = ffa_endpoint_destination(x1); 312 struct secure_partition_desc *sp; 313 unsigned int idx; 314 315 /* Check if arg2 has been populated correctly based on message type. */ 316 if (!direct_msg_validate_arg2(x2)) { 317 return spmc_ffa_error_return(handle, 318 FFA_ERROR_INVALID_PARAMETER); 319 } 320 321 /* Check that the response did not originate from the Normal world. */ 322 if (!secure_origin) { 323 VERBOSE("Direct Response not supported from Normal World.\n"); 324 return spmc_ffa_error_return(handle, 325 FFA_ERROR_INVALID_PARAMETER); 326 } 327 328 /* 329 * Check that the response is either targeted to the Normal world or the 330 * SPMC e.g. a PM response. 331 */ 332 if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) { 333 VERBOSE("Direct response to invalid partition ID (0x%x).\n", 334 dst_id); 335 return spmc_ffa_error_return(handle, 336 FFA_ERROR_INVALID_PARAMETER); 337 } 338 339 /* Obtain the SP descriptor and update its runtime state. */ 340 sp = spmc_get_sp_ctx(ffa_endpoint_source(x1)); 341 if (sp == NULL) { 342 VERBOSE("Direct response to unknown partition ID (0x%x).\n", 343 dst_id); 344 return spmc_ffa_error_return(handle, 345 FFA_ERROR_INVALID_PARAMETER); 346 } 347 348 /* Sanity check state is being tracked correctly in the SPMC. */ 349 idx = get_ec_index(sp); 350 assert(sp->ec[idx].rt_state == RT_STATE_RUNNING); 351 352 /* Ensure SP execution context was in the right runtime model. */ 353 if (sp->ec[idx].rt_model != RT_MODEL_DIR_REQ) { 354 VERBOSE("SP context on core%u not handling direct req (%u).\n", 355 idx, sp->ec[idx].rt_model); 356 return spmc_ffa_error_return(handle, FFA_ERROR_DENIED); 357 } 358 359 /* Update the state of the SP execution context. */ 360 sp->ec[idx].rt_state = RT_STATE_WAITING; 361 362 /* 363 * If the receiver is not the SPMC then forward the response to the 364 * Normal world. 365 */ 366 if (dst_id == FFA_SPMC_ID) { 367 spmc_sp_synchronous_exit(&sp->ec[idx], x4); 368 /* Should not get here. */ 369 panic(); 370 } 371 372 return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4, 373 handle, cookie, flags, dst_id); 374 } 375 376 /******************************************************************************* 377 * This function handles the FFA_MSG_WAIT SMC to allow an SP to relinquish its 378 * cycles. 379 ******************************************************************************/ 380 static uint64_t msg_wait_handler(uint32_t smc_fid, 381 bool secure_origin, 382 uint64_t x1, 383 uint64_t x2, 384 uint64_t x3, 385 uint64_t x4, 386 void *cookie, 387 void *handle, 388 uint64_t flags) 389 { 390 struct secure_partition_desc *sp; 391 unsigned int idx; 392 393 /* 394 * Check that the response did not originate from the Normal world as 395 * only the secure world can call this ABI. 396 */ 397 if (!secure_origin) { 398 VERBOSE("Normal world cannot call FFA_MSG_WAIT.\n"); 399 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 400 } 401 402 /* Get the descriptor of the SP that invoked FFA_MSG_WAIT. */ 403 sp = spmc_get_current_sp_ctx(); 404 if (sp == NULL) { 405 return spmc_ffa_error_return(handle, 406 FFA_ERROR_INVALID_PARAMETER); 407 } 408 409 /* 410 * Get the execution context of the SP that invoked FFA_MSG_WAIT. 411 */ 412 idx = get_ec_index(sp); 413 414 /* Ensure SP execution context was in the right runtime model. */ 415 if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) { 416 return spmc_ffa_error_return(handle, FFA_ERROR_DENIED); 417 } 418 419 /* Sanity check the state is being tracked correctly in the SPMC. */ 420 assert(sp->ec[idx].rt_state == RT_STATE_RUNNING); 421 422 /* 423 * Perform a synchronous exit if the partition was initialising. The 424 * state is updated after the exit. 425 */ 426 if (sp->ec[idx].rt_model == RT_MODEL_INIT) { 427 spmc_sp_synchronous_exit(&sp->ec[idx], x4); 428 /* Should not get here */ 429 panic(); 430 } 431 432 /* Update the state of the SP execution context. */ 433 sp->ec[idx].rt_state = RT_STATE_WAITING; 434 435 /* Resume normal world if a secure interrupt was handled. */ 436 if (sp->ec[idx].rt_model == RT_MODEL_INTR) { 437 /* FFA_MSG_WAIT can only be called from the secure world. */ 438 unsigned int secure_state_in = SECURE; 439 unsigned int secure_state_out = NON_SECURE; 440 441 cm_el1_sysregs_context_save(secure_state_in); 442 cm_el1_sysregs_context_restore(secure_state_out); 443 cm_set_next_eret_context(secure_state_out); 444 SMC_RET0(cm_get_context(secure_state_out)); 445 } 446 447 /* Forward the response to the Normal world. */ 448 return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4, 449 handle, cookie, flags, FFA_NWD_ID); 450 } 451 452 static uint64_t ffa_error_handler(uint32_t smc_fid, 453 bool secure_origin, 454 uint64_t x1, 455 uint64_t x2, 456 uint64_t x3, 457 uint64_t x4, 458 void *cookie, 459 void *handle, 460 uint64_t flags) 461 { 462 struct secure_partition_desc *sp; 463 unsigned int idx; 464 465 /* Check that the response did not originate from the Normal world. */ 466 if (!secure_origin) { 467 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 468 } 469 470 /* Get the descriptor of the SP that invoked FFA_ERROR. */ 471 sp = spmc_get_current_sp_ctx(); 472 if (sp == NULL) { 473 return spmc_ffa_error_return(handle, 474 FFA_ERROR_INVALID_PARAMETER); 475 } 476 477 /* Get the execution context of the SP that invoked FFA_ERROR. */ 478 idx = get_ec_index(sp); 479 480 /* 481 * We only expect FFA_ERROR to be received during SP initialisation 482 * otherwise this is an invalid call. 483 */ 484 if (sp->ec[idx].rt_model == RT_MODEL_INIT) { 485 ERROR("SP 0x%x failed to initialize.\n", sp->sp_id); 486 spmc_sp_synchronous_exit(&sp->ec[idx], x2); 487 /* Should not get here. */ 488 panic(); 489 } 490 491 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 492 } 493 494 /******************************************************************************* 495 * This function will parse the Secure Partition Manifest. From manifest, it 496 * will fetch details for preparing Secure partition image context and secure 497 * partition image boot arguments if any. 498 ******************************************************************************/ 499 static int sp_manifest_parse(void *sp_manifest, int offset, 500 struct secure_partition_desc *sp, 501 entry_point_info_t *ep_info) 502 { 503 int32_t ret, node; 504 uint32_t config_32; 505 506 /* 507 * Look for the mandatory fields that are expected to be present in 508 * the SP manifests. 509 */ 510 node = fdt_path_offset(sp_manifest, "/"); 511 if (node < 0) { 512 ERROR("Did not find root node.\n"); 513 return node; 514 } 515 516 ret = fdt_read_uint32_array(sp_manifest, node, "uuid", 517 ARRAY_SIZE(sp->uuid), sp->uuid); 518 if (ret != 0) { 519 ERROR("Missing Secure Partition UUID.\n"); 520 return ret; 521 } 522 523 ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32); 524 if (ret != 0) { 525 ERROR("Missing SP Exception Level information.\n"); 526 return ret; 527 } 528 529 sp->runtime_el = config_32; 530 531 ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32); 532 if (ret != 0) { 533 ERROR("Missing Secure Partition FF-A Version.\n"); 534 return ret; 535 } 536 537 sp->ffa_version = config_32; 538 539 ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32); 540 if (ret != 0) { 541 ERROR("Missing Secure Partition Execution State.\n"); 542 return ret; 543 } 544 545 sp->execution_state = config_32; 546 547 ret = fdt_read_uint32(sp_manifest, node, 548 "messaging-method", &config_32); 549 if (ret != 0) { 550 ERROR("Missing Secure Partition messaging method.\n"); 551 return ret; 552 } 553 554 /* Validate this entry, we currently only support direct messaging. */ 555 if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV | 556 FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) { 557 WARN("Invalid Secure Partition messaging method (0x%x)\n", 558 config_32); 559 return -EINVAL; 560 } 561 562 sp->properties = config_32; 563 564 ret = fdt_read_uint32(sp_manifest, node, 565 "execution-ctx-count", &config_32); 566 567 if (ret != 0) { 568 ERROR("Missing SP Execution Context Count.\n"); 569 return ret; 570 } 571 572 /* 573 * Ensure this field is set correctly in the manifest however 574 * since this is currently a hardcoded value for S-EL1 partitions 575 * we don't need to save it here, just validate. 576 */ 577 if (config_32 != PLATFORM_CORE_COUNT) { 578 ERROR("SP Execution Context Count (%u) must be %u.\n", 579 config_32, PLATFORM_CORE_COUNT); 580 return -EINVAL; 581 } 582 583 /* 584 * Look for the optional fields that are expected to be present in 585 * an SP manifest. 586 */ 587 ret = fdt_read_uint32(sp_manifest, node, "id", &config_32); 588 if (ret != 0) { 589 WARN("Missing Secure Partition ID.\n"); 590 } else { 591 if (!is_ffa_secure_id_valid(config_32)) { 592 ERROR("Invalid Secure Partition ID (0x%x).\n", 593 config_32); 594 return -EINVAL; 595 } 596 sp->sp_id = config_32; 597 } 598 599 return 0; 600 } 601 602 /******************************************************************************* 603 * This function gets the Secure Partition Manifest base and maps the manifest 604 * region. 605 * Currently only one Secure Partition manifest is considered which is used to 606 * prepare the context for the single Secure Partition. 607 ******************************************************************************/ 608 static int find_and_prepare_sp_context(void) 609 { 610 void *sp_manifest; 611 uintptr_t manifest_base; 612 uintptr_t manifest_base_align; 613 entry_point_info_t *next_image_ep_info; 614 int32_t ret; 615 struct secure_partition_desc *sp; 616 617 next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE); 618 if (next_image_ep_info == NULL) { 619 WARN("No Secure Partition image provided by BL2.\n"); 620 return -ENOENT; 621 } 622 623 sp_manifest = (void *)next_image_ep_info->args.arg0; 624 if (sp_manifest == NULL) { 625 WARN("Secure Partition manifest absent.\n"); 626 return -ENOENT; 627 } 628 629 manifest_base = (uintptr_t)sp_manifest; 630 manifest_base_align = page_align(manifest_base, DOWN); 631 632 /* 633 * Map the secure partition manifest region in the EL3 translation 634 * regime. 635 * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base 636 * alignment the region of 1 PAGE_SIZE from manifest align base may 637 * not completely accommodate the secure partition manifest region. 638 */ 639 ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align, 640 manifest_base_align, 641 PAGE_SIZE * 2, 642 MT_RO_DATA); 643 if (ret != 0) { 644 ERROR("Error while mapping SP manifest (%d).\n", ret); 645 return ret; 646 } 647 648 ret = fdt_node_offset_by_compatible(sp_manifest, -1, 649 "arm,ffa-manifest-1.0"); 650 if (ret < 0) { 651 ERROR("Error happened in SP manifest reading.\n"); 652 return -EINVAL; 653 } 654 655 /* 656 * Store the size of the manifest so that it can be used later to pass 657 * the manifest as boot information later. 658 */ 659 next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest); 660 INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1); 661 662 /* 663 * Select an SP descriptor for initialising the partition's execution 664 * context on the primary CPU. 665 */ 666 sp = spmc_get_current_sp_ctx(); 667 668 /* Initialize entry point information for the SP */ 669 SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1, 670 SECURE | EP_ST_ENABLE); 671 672 /* Parse the SP manifest. */ 673 ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info); 674 if (ret != 0) { 675 ERROR("Error in Secure Partition manifest parsing.\n"); 676 return ret; 677 } 678 679 /* Check that the runtime EL in the manifest was correct. */ 680 if (sp->runtime_el != S_EL1) { 681 ERROR("Unexpected runtime EL: %d\n", sp->runtime_el); 682 return -EINVAL; 683 } 684 685 /* Perform any common initialisation. */ 686 spmc_sp_common_setup(sp, next_image_ep_info); 687 688 /* Perform any initialisation specific to S-EL1 SPs. */ 689 spmc_el1_sp_setup(sp, next_image_ep_info); 690 691 /* Initialize the SP context with the required ep info. */ 692 spmc_sp_common_ep_commit(sp, next_image_ep_info); 693 694 return 0; 695 } 696 697 /******************************************************************************* 698 * This function takes an SP context pointer and performs a synchronous entry 699 * into it. 700 ******************************************************************************/ 701 static int32_t logical_sp_init(void) 702 { 703 int32_t rc = 0; 704 struct el3_lp_desc *el3_lp_descs; 705 706 /* Perform initial validation of the Logical Partitions. */ 707 rc = el3_sp_desc_validate(); 708 if (rc != 0) { 709 ERROR("Logical Partition validation failed!\n"); 710 return rc; 711 } 712 713 el3_lp_descs = get_el3_lp_array(); 714 715 INFO("Logical Secure Partition init start.\n"); 716 for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) { 717 rc = el3_lp_descs[i].init(); 718 if (rc != 0) { 719 ERROR("Logical SP (0x%x) Failed to Initialize\n", 720 el3_lp_descs[i].sp_id); 721 return rc; 722 } 723 VERBOSE("Logical SP (0x%x) Initialized\n", 724 el3_lp_descs[i].sp_id); 725 } 726 727 INFO("Logical Secure Partition init completed.\n"); 728 729 return rc; 730 } 731 732 uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec) 733 { 734 uint64_t rc; 735 736 assert(ec != NULL); 737 738 /* Assign the context of the SP to this CPU */ 739 cm_set_context(&(ec->cpu_ctx), SECURE); 740 741 /* Restore the context assigned above */ 742 cm_el1_sysregs_context_restore(SECURE); 743 cm_set_next_eret_context(SECURE); 744 745 /* Invalidate TLBs at EL1. */ 746 tlbivmalle1(); 747 dsbish(); 748 749 /* Enter Secure Partition */ 750 rc = spm_secure_partition_enter(&ec->c_rt_ctx); 751 752 /* Save secure state */ 753 cm_el1_sysregs_context_save(SECURE); 754 755 return rc; 756 } 757 758 /******************************************************************************* 759 * SPMC Helper Functions. 760 ******************************************************************************/ 761 static int32_t sp_init(void) 762 { 763 uint64_t rc; 764 struct secure_partition_desc *sp; 765 struct sp_exec_ctx *ec; 766 767 sp = spmc_get_current_sp_ctx(); 768 ec = spmc_get_sp_ec(sp); 769 ec->rt_model = RT_MODEL_INIT; 770 ec->rt_state = RT_STATE_RUNNING; 771 772 INFO("Secure Partition (0x%x) init start.\n", sp->sp_id); 773 774 rc = spmc_sp_synchronous_entry(ec); 775 if (rc != 0) { 776 /* Indicate SP init was not successful. */ 777 ERROR("SP (0x%x) failed to initialize (%lu).\n", 778 sp->sp_id, rc); 779 return 0; 780 } 781 782 ec->rt_state = RT_STATE_WAITING; 783 INFO("Secure Partition initialized.\n"); 784 785 return 1; 786 } 787 788 static void initalize_sp_descs(void) 789 { 790 struct secure_partition_desc *sp; 791 792 for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { 793 sp = &sp_desc[i]; 794 sp->sp_id = INV_SP_ID; 795 sp->mailbox.rx_buffer = NULL; 796 sp->mailbox.tx_buffer = NULL; 797 sp->mailbox.state = MAILBOX_STATE_EMPTY; 798 sp->secondary_ep = 0; 799 } 800 } 801 802 static void initalize_ns_ep_descs(void) 803 { 804 struct ns_endpoint_desc *ns_ep; 805 806 for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) { 807 ns_ep = &ns_ep_desc[i]; 808 /* 809 * Clashes with the Hypervisor ID but will not be a 810 * problem in practice. 811 */ 812 ns_ep->ns_ep_id = 0; 813 ns_ep->ffa_version = 0; 814 ns_ep->mailbox.rx_buffer = NULL; 815 ns_ep->mailbox.tx_buffer = NULL; 816 ns_ep->mailbox.state = MAILBOX_STATE_EMPTY; 817 } 818 } 819 820 /******************************************************************************* 821 * Initialize SPMC attributes for the SPMD. 822 ******************************************************************************/ 823 void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs) 824 { 825 spmc_attrs->major_version = FFA_VERSION_MAJOR; 826 spmc_attrs->minor_version = FFA_VERSION_MINOR; 827 spmc_attrs->exec_state = MODE_RW_64; 828 spmc_attrs->spmc_id = FFA_SPMC_ID; 829 } 830 831 /******************************************************************************* 832 * Initialize contexts of all Secure Partitions. 833 ******************************************************************************/ 834 int32_t spmc_setup(void) 835 { 836 int32_t ret; 837 838 /* Initialize endpoint descriptors */ 839 initalize_sp_descs(); 840 initalize_ns_ep_descs(); 841 842 /* Setup logical SPs. */ 843 ret = logical_sp_init(); 844 if (ret != 0) { 845 ERROR("Failed to initialize Logical Partitions.\n"); 846 return ret; 847 } 848 849 /* Perform physical SP setup. */ 850 851 /* Disable MMU at EL1 (initialized by BL2) */ 852 disable_mmu_icache_el1(); 853 854 /* Initialize context of the SP */ 855 INFO("Secure Partition context setup start.\n"); 856 857 ret = find_and_prepare_sp_context(); 858 if (ret != 0) { 859 ERROR("Error in SP finding and context preparation.\n"); 860 return ret; 861 } 862 863 /* Register init function for deferred init. */ 864 bl31_register_bl32_init(&sp_init); 865 866 INFO("Secure Partition setup done.\n"); 867 868 return 0; 869 } 870 871 /******************************************************************************* 872 * Secure Partition Manager SMC handler. 873 ******************************************************************************/ 874 uint64_t spmc_smc_handler(uint32_t smc_fid, 875 bool secure_origin, 876 uint64_t x1, 877 uint64_t x2, 878 uint64_t x3, 879 uint64_t x4, 880 void *cookie, 881 void *handle, 882 uint64_t flags) 883 { 884 switch (smc_fid) { 885 886 case FFA_MSG_SEND_DIRECT_REQ_SMC32: 887 case FFA_MSG_SEND_DIRECT_REQ_SMC64: 888 return direct_req_smc_handler(smc_fid, secure_origin, x1, x2, 889 x3, x4, cookie, handle, flags); 890 891 case FFA_MSG_SEND_DIRECT_RESP_SMC32: 892 case FFA_MSG_SEND_DIRECT_RESP_SMC64: 893 return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2, 894 x3, x4, cookie, handle, flags); 895 896 case FFA_MSG_WAIT: 897 return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4, 898 cookie, handle, flags); 899 900 case FFA_ERROR: 901 return ffa_error_handler(smc_fid, secure_origin, x1, x2, x3, x4, 902 cookie, handle, flags); 903 904 default: 905 WARN("Unsupported FF-A call 0x%08x.\n", smc_fid); 906 break; 907 } 908 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 909 } 910