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