1 /* 2 * Copyright (c) 2020-2025, 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 #include <inttypes.h> 10 #include <stdint.h> 11 #include <string.h> 12 13 #include <arch_helpers.h> 14 #include <arch/aarch64/arch_features.h> 15 #include <bl31/bl31.h> 16 #include <bl31/interrupt_mgmt.h> 17 #include <common/debug.h> 18 #include <common/runtime_svc.h> 19 #include <common/tbbr/tbbr_img_def.h> 20 #include <lib/el3_runtime/context_mgmt.h> 21 #include <lib/fconf/fconf.h> 22 #include <lib/fconf/fconf_dyn_cfg_getter.h> 23 #include <lib/per_cpu/per_cpu.h> 24 #include <lib/smccc.h> 25 #include <lib/spinlock.h> 26 #include <lib/utils.h> 27 #include <lib/xlat_tables/xlat_tables_v2.h> 28 #include <plat/common/common_def.h> 29 #include <plat/common/platform.h> 30 #include <platform_def.h> 31 #include <services/el3_spmd_logical_sp.h> 32 #include <services/ffa_svc.h> 33 #include <services/spmc_svc.h> 34 #include <services/spmd_svc.h> 35 #include <smccc_helpers.h> 36 #include "spmd_private.h" 37 #if TRANSFER_LIST 38 #include <transfer_list.h> 39 #endif 40 41 /******************************************************************************* 42 * SPM Core context information. 43 ******************************************************************************/ 44 static PER_CPU_DEFINE(spmd_spm_core_context_t, spm_core_context); 45 46 /******************************************************************************* 47 * SPM Core attribute information is read from its manifest if the SPMC is not 48 * at EL3. Else, it is populated from the SPMC directly. 49 ******************************************************************************/ 50 static spmc_manifest_attribute_t spmc_attrs; 51 52 /******************************************************************************* 53 * FFA version used by nonsecure endpoint. 54 ******************************************************************************/ 55 static uint32_t nonsecure_ffa_version; 56 57 /******************************************************************************* 58 * Whether the normal world finished negotiating its version. 59 ******************************************************************************/ 60 static bool nonsecure_version_negotiated; 61 62 /******************************************************************************* 63 * FFA version used by SPMC, as seen by the normal world. 64 ******************************************************************************/ 65 static uint32_t spmc_nwd_ffa_version; 66 67 /******************************************************************************* 68 * SPM Core entry point information. Discovered on the primary core and reused 69 * on secondary cores. 70 ******************************************************************************/ 71 static entry_point_info_t *spmc_ep_info; 72 73 /******************************************************************************* 74 * SPM Core context on current CPU get helper. 75 ******************************************************************************/ 76 spmd_spm_core_context_t *spmd_get_context(void) 77 { 78 return PER_CPU_CUR(spm_core_context); 79 } 80 81 /******************************************************************************* 82 * SPM Core ID getter. 83 ******************************************************************************/ 84 uint16_t spmd_spmc_id_get(void) 85 { 86 return spmc_attrs.spmc_id; 87 } 88 89 /******************************************************************************* 90 * Static function declaration. 91 ******************************************************************************/ 92 static int32_t spmd_init(void); 93 static int spmd_spmc_init(void *pm_addr); 94 95 static uint64_t spmd_smc_forward(uint32_t smc_fid, 96 bool secure_origin, 97 uint64_t x1, 98 uint64_t x2, 99 uint64_t x3, 100 uint64_t x4, 101 void *cookie, 102 void *handle, 103 uint64_t flags, 104 uint32_t secure_ffa_version); 105 106 /****************************************************************************** 107 * Builds an SPMD to SPMC direct message request. 108 *****************************************************************************/ 109 void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target_func, 110 unsigned long long message) 111 { 112 write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32); 113 write_ctx_reg(gpregs, CTX_GPREG_X1, 114 (SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) | 115 spmd_spmc_id_get()); 116 write_ctx_reg(gpregs, CTX_GPREG_X2, BIT(31) | target_func); 117 write_ctx_reg(gpregs, CTX_GPREG_X3, message); 118 119 /* Zero out x4-x7 for the direct request emitted towards the SPMC. */ 120 write_ctx_reg(gpregs, CTX_GPREG_X4, 0); 121 write_ctx_reg(gpregs, CTX_GPREG_X5, 0); 122 write_ctx_reg(gpregs, CTX_GPREG_X6, 0); 123 write_ctx_reg(gpregs, CTX_GPREG_X7, 0); 124 } 125 126 127 /******************************************************************************* 128 * This function takes an SPMC context pointer and performs a synchronous 129 * SPMC entry. 130 ******************************************************************************/ 131 uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) 132 { 133 uint64_t rc; 134 135 assert(spmc_ctx != NULL); 136 137 cm_set_context(&(spmc_ctx->cpu_ctx), SECURE); 138 139 /* Restore the context assigned above */ 140 #if SPMD_SPM_AT_SEL2 141 cm_el2_sysregs_context_restore(SECURE); 142 #else 143 cm_el1_sysregs_context_restore(SECURE); 144 #endif 145 cm_set_next_eret_context(SECURE); 146 147 /* Enter SPMC */ 148 rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx); 149 150 /* Save secure state */ 151 #if SPMD_SPM_AT_SEL2 152 cm_el2_sysregs_context_save(SECURE); 153 #else 154 cm_el1_sysregs_context_save(SECURE); 155 #endif 156 157 return rc; 158 } 159 160 /******************************************************************************* 161 * This function returns to the place where spmd_spm_core_sync_entry() was 162 * called originally. 163 ******************************************************************************/ 164 __dead2 void spmd_spm_core_sync_exit(uint64_t rc) 165 { 166 spmd_spm_core_context_t *ctx = spmd_get_context(); 167 168 /* Get current CPU context from SPMC context */ 169 assert(cm_get_context(SECURE) == &(ctx->cpu_ctx)); 170 171 /* 172 * The SPMD must have initiated the original request through a 173 * synchronous entry into SPMC. Jump back to the original C runtime 174 * context with the value of rc in x0; 175 */ 176 spmd_spm_core_exit(ctx->c_rt_ctx, rc); 177 178 panic(); 179 } 180 181 void spmd_setup_context(unsigned int core_id) 182 { 183 cpu_context_t *cpu_ctx; 184 185 PER_CPU_CUR(spm_core_context)->state = SPMC_STATE_OFF; 186 187 /* Setup an initial cpu context for the SPMC. */ 188 cpu_ctx = &(PER_CPU_CUR(spm_core_context)->cpu_ctx); 189 cm_setup_context(cpu_ctx, spmc_ep_info); 190 191 /* 192 * Pass the core linear ID to the SPMC through x4. 193 * (TF-A implementation defined behavior helping 194 * a legacy TOS migration to adopt FF-A). 195 */ 196 write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4, core_id); 197 } 198 199 /******************************************************************************* 200 * Jump to the SPM Core for the first time. 201 ******************************************************************************/ 202 static int32_t spmd_init(void) 203 { 204 spmd_spm_core_context_t *ctx = spmd_get_context(); 205 uint64_t rc; 206 207 VERBOSE("SPM Core init start.\n"); 208 209 /* Primary boot core enters the SPMC for initialization. */ 210 ctx->state = SPMC_STATE_ON_PENDING; 211 212 rc = spmd_spm_core_sync_entry(ctx); 213 if (rc != 0ULL) { 214 ERROR("SPMC initialisation failed 0x%" PRIx64 "\n", rc); 215 return 0; 216 } 217 218 ctx->state = SPMC_STATE_ON; 219 220 VERBOSE("SPM Core init end.\n"); 221 222 spmd_logical_sp_set_spmc_initialized(); 223 rc = spmd_logical_sp_init(); 224 if (rc != 0) { 225 WARN("SPMD Logical partitions failed init.\n"); 226 } 227 228 return 1; 229 } 230 231 /******************************************************************************* 232 * spmd_secure_interrupt_handler 233 * Enter the SPMC for further handling of the secure interrupt by the SPMC 234 * itself or a Secure Partition. 235 ******************************************************************************/ 236 static uint64_t spmd_secure_interrupt_handler(uint32_t id, 237 uint32_t flags, 238 void *handle, 239 void *cookie) 240 { 241 spmd_spm_core_context_t *ctx = spmd_get_context(); 242 gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx); 243 int64_t rc; 244 245 /* Sanity check the security state when the exception was generated */ 246 assert(get_interrupt_src_ss(flags) == NON_SECURE); 247 248 /* Sanity check the pointer to this cpu's context */ 249 assert(handle == cm_get_context(NON_SECURE)); 250 251 /* Save the non-secure context before entering SPMC */ 252 #if SPMD_SPM_AT_SEL2 253 cm_el2_sysregs_context_save(NON_SECURE); 254 #else 255 cm_el1_sysregs_context_save(NON_SECURE); 256 257 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS 258 /* 259 * The hint bit denoting absence of SVE live state is effectively false 260 * in this scenario where execution was trapped to EL3 due to FIQ. 261 */ 262 simd_ctx_save(NON_SECURE, false); 263 simd_ctx_restore(SECURE); 264 #endif 265 #endif 266 267 /* Convey the event to the SPMC through the FFA_INTERRUPT interface. */ 268 write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_INTERRUPT); 269 write_ctx_reg(gpregs, CTX_GPREG_X1, 0); 270 write_ctx_reg(gpregs, CTX_GPREG_X2, 0); 271 write_ctx_reg(gpregs, CTX_GPREG_X3, 0); 272 write_ctx_reg(gpregs, CTX_GPREG_X4, 0); 273 write_ctx_reg(gpregs, CTX_GPREG_X5, 0); 274 write_ctx_reg(gpregs, CTX_GPREG_X6, 0); 275 write_ctx_reg(gpregs, CTX_GPREG_X7, 0); 276 277 /* Mark current core as handling a secure interrupt. */ 278 ctx->secure_interrupt_ongoing = true; 279 280 rc = spmd_spm_core_sync_entry(ctx); 281 282 if (rc != 0ULL) { 283 ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, plat_my_core_pos()); 284 } 285 286 ctx->secure_interrupt_ongoing = false; 287 288 #if SPMD_SPM_AT_SEL2 289 cm_el2_sysregs_context_restore(NON_SECURE); 290 #else 291 cm_el1_sysregs_context_restore(NON_SECURE); 292 293 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS 294 simd_ctx_save(SECURE, false); 295 simd_ctx_restore(NON_SECURE); 296 #endif 297 #endif 298 cm_set_next_eret_context(NON_SECURE); 299 300 SMC_RET0(&ctx->cpu_ctx); 301 } 302 303 #if (EL3_EXCEPTION_HANDLING == 0) 304 /******************************************************************************* 305 * spmd_group0_interrupt_handler_nwd 306 * 307 * Group0 secure interrupt in the normal world are trapped to EL3. Delegate the 308 * handling of the interrupt to the platform handler, and return only upon 309 * successfully handling the Group0 interrupt. 310 * 311 * NOTE: the generic handle_interrupt_exception entry calls 312 * plat_ic_get_pending_interrupt_type to perform a first triage and route to 313 * the corresponding interrupt handler based on the interrupt type. 314 * A registered handler must not assume that the HPPI hasn't changed from the 315 * top level handler until reaching to it. The first thing a handler must do is 316 * attempting to acknowledge the interrupt and process it if it's a valid 317 * INTID. Meanwhile, the interrupt might have been acknowledged by another 318 * PE, or another high priority interrupt got asserted, or any other valid 319 * reason for the HPPI to change. The reasoning is the same for an interrupt 320 * delegated by lower EL through the FFA_EL3_INTR_HANDLE interface. 321 * For a G0 interrupt triggered while secure world runs, the first triage is 322 * done by lower EL e.g. S-EL2 and routes it to EL3 for handling. Once there, 323 * the HPPI might have changed so the same rules as above apply. 324 * 325 ******************************************************************************/ 326 static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id, 327 uint32_t flags, 328 void *handle, 329 void *cookie) 330 { 331 uint32_t intid, intr_raw; 332 333 /* Sanity check the security state when the exception was generated. */ 334 assert(get_interrupt_src_ss(flags) == NON_SECURE); 335 336 /* Sanity check the pointer to this cpu's context. */ 337 assert(handle == cm_get_context(NON_SECURE)); 338 339 assert(id == INTR_ID_UNAVAILABLE); 340 341 intr_raw = plat_ic_acknowledge_interrupt(); 342 intid = plat_ic_get_interrupt_id(intr_raw); 343 344 if (intid == INTR_ID_UNAVAILABLE) { 345 return 0U; 346 } 347 348 if (plat_spmd_handle_group0_interrupt(intid) < 0) { 349 ERROR("Group0 interrupt %u not handled\n", intid); 350 panic(); 351 } 352 353 /* Deactivate the corresponding Group0 interrupt. */ 354 plat_ic_end_of_interrupt(intid); 355 356 return 0U; 357 } 358 #endif 359 360 /******************************************************************************* 361 * spmd_handle_group0_intr_swd 362 * 363 * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using 364 * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the 365 * interrupt to the platform handler, and returns only upon successfully 366 * handling the Group0 interrupt. 367 * 368 * NOTE: see spmd_group0_interrupt_handler_nwd note section. 369 ******************************************************************************/ 370 static uint64_t spmd_handle_group0_intr_swd(void *handle) 371 { 372 uint32_t intid, intr_raw; 373 374 /* Sanity check the pointer to this cpu's context */ 375 assert(handle == cm_get_context(SECURE)); 376 377 intr_raw = plat_ic_acknowledge_interrupt(); 378 intid = plat_ic_get_interrupt_id(intr_raw); 379 380 if (intid == INTR_ID_UNAVAILABLE) { 381 return 0U; 382 } 383 384 /* 385 * TODO: Currently due to a limitation in SPMD implementation, the 386 * platform handler is expected to not delegate handling to NWd while 387 * processing Group0 secure interrupt. 388 */ 389 if (plat_spmd_handle_group0_interrupt(intid) < 0) { 390 /* Group0 interrupt was not handled by the platform. */ 391 ERROR("Group0 interrupt %u not handled\n", intid); 392 panic(); 393 } 394 395 /* Deactivate the corresponding Group0 interrupt. */ 396 plat_ic_end_of_interrupt(intid); 397 398 /* Return success. */ 399 SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 400 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 401 FFA_PARAM_MBZ); 402 } 403 404 #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 405 static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size, 406 unsigned int attr, uintptr_t *align_addr, 407 size_t *align_size) 408 { 409 uintptr_t base_addr_align; 410 size_t mapped_size_align; 411 int rc; 412 413 /* Page aligned address and size if necessary */ 414 base_addr_align = page_align(base_addr, DOWN); 415 mapped_size_align = page_align(size, UP); 416 417 if ((base_addr != base_addr_align) && 418 (size == mapped_size_align)) { 419 mapped_size_align += PAGE_SIZE; 420 } 421 422 /* 423 * Map dynamically given region with its aligned base address and 424 * size 425 */ 426 rc = mmap_add_dynamic_region((unsigned long long)base_addr_align, 427 base_addr_align, 428 mapped_size_align, 429 attr); 430 if (rc == 0) { 431 *align_addr = base_addr_align; 432 *align_size = mapped_size_align; 433 } 434 435 return rc; 436 } 437 438 static void spmd_do_sec_cpy(uintptr_t root_base_addr, uintptr_t sec_base_addr, 439 size_t size) 440 { 441 uintptr_t root_base_addr_align, sec_base_addr_align; 442 size_t root_mapped_size_align, sec_mapped_size_align; 443 int rc; 444 445 assert(root_base_addr != 0UL); 446 assert(sec_base_addr != 0UL); 447 assert(size != 0UL); 448 449 /* Map the memory with required attributes */ 450 rc = spmd_dynamic_map_mem(root_base_addr, size, MT_RO_DATA | MT_ROOT, 451 &root_base_addr_align, 452 &root_mapped_size_align); 453 if (rc != 0) { 454 ERROR("%s %s %lu (%d)\n", "Error while mapping", "root region", 455 root_base_addr, rc); 456 panic(); 457 } 458 459 rc = spmd_dynamic_map_mem(sec_base_addr, size, MT_RW_DATA | MT_SECURE, 460 &sec_base_addr_align, &sec_mapped_size_align); 461 if (rc != 0) { 462 ERROR("%s %s %lu (%d)\n", "Error while mapping", 463 "secure region", sec_base_addr, rc); 464 panic(); 465 } 466 467 /* Do copy operation */ 468 (void)memcpy((void *)sec_base_addr, (void *)root_base_addr, size); 469 470 /* Unmap root memory region */ 471 rc = mmap_remove_dynamic_region(root_base_addr_align, 472 root_mapped_size_align); 473 if (rc != 0) { 474 ERROR("%s %s %lu (%d)\n", "Error while unmapping", 475 "root region", root_base_addr_align, rc); 476 panic(); 477 } 478 479 /* Unmap secure memory region */ 480 rc = mmap_remove_dynamic_region(sec_base_addr_align, 481 sec_mapped_size_align); 482 if (rc != 0) { 483 ERROR("%s %s %lu (%d)\n", "Error while unmapping", 484 "secure region", sec_base_addr_align, rc); 485 panic(); 486 } 487 } 488 #endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */ 489 490 /******************************************************************************* 491 * Loads SPMC manifest and inits SPMC. 492 ******************************************************************************/ 493 static int spmd_spmc_init(void *pm_addr) 494 { 495 uint32_t ep_attr, flags; 496 int rc; 497 const struct dyn_cfg_dtb_info_t *image_info __unused; 498 499 /* Load the SPM Core manifest */ 500 rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr); 501 if (rc != 0) { 502 WARN("No or invalid SPM Core manifest image provided by BL2\n"); 503 return rc; 504 } 505 506 /* 507 * Ensure that the SPM Core version is compatible with the SPM 508 * Dispatcher version. 509 */ 510 if ((spmc_attrs.major_version != FFA_VERSION_MAJOR) || 511 (spmc_attrs.minor_version > FFA_VERSION_MINOR)) { 512 WARN("Unsupported FFA version (%u.%u)\n", 513 spmc_attrs.major_version, spmc_attrs.minor_version); 514 return -EINVAL; 515 } 516 517 VERBOSE("FFA version (%u.%u)\n", spmc_attrs.major_version, 518 spmc_attrs.minor_version); 519 520 VERBOSE("SPM Core run time EL%x.\n", 521 SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); 522 523 /* Validate the SPMC ID, Ensure high bit is set */ 524 if (((spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & 525 SPMC_SECURE_ID_MASK) == 0U) { 526 WARN("Invalid ID (0x%x) for SPMC.\n", spmc_attrs.spmc_id); 527 return -EINVAL; 528 } 529 530 /* Validate the SPM Core execution state */ 531 if ((spmc_attrs.exec_state != MODE_RW_64) && 532 (spmc_attrs.exec_state != MODE_RW_32)) { 533 WARN("Unsupported %s%x.\n", "SPM Core execution state 0x", 534 spmc_attrs.exec_state); 535 return -EINVAL; 536 } 537 538 VERBOSE("%s%x.\n", "SPM Core execution state 0x", 539 spmc_attrs.exec_state); 540 541 #if SPMD_SPM_AT_SEL2 542 /* Ensure manifest has not requested AArch32 state in S-EL2 */ 543 if (spmc_attrs.exec_state == MODE_RW_32) { 544 WARN("AArch32 state at S-EL2 is not supported.\n"); 545 return -EINVAL; 546 } 547 548 /* 549 * Check if S-EL2 is supported on this system if S-EL2 550 * is required for SPM 551 */ 552 if (!is_feat_sel2_supported()) { 553 WARN("SPM Core run time S-EL2 is not supported.\n"); 554 return -EINVAL; 555 } 556 #endif /* SPMD_SPM_AT_SEL2 */ 557 558 /* Initialise an entrypoint to set up the CPU context */ 559 ep_attr = SECURE | EP_ST_ENABLE; 560 if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0ULL) { 561 ep_attr |= EP_EE_BIG; 562 } 563 564 SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr); 565 566 /* 567 * Populate SPSR for SPM Core based upon validated parameters from the 568 * manifest. 569 */ 570 if (spmc_attrs.exec_state == MODE_RW_32) { 571 spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, 572 SPSR_E_LITTLE, 573 DAIF_FIQ_BIT | 574 DAIF_IRQ_BIT | 575 DAIF_ABT_BIT); 576 } else { 577 578 #if SPMD_SPM_AT_SEL2 579 static const uint32_t runtime_el = MODE_EL2; 580 #else 581 static const uint32_t runtime_el = MODE_EL1; 582 #endif 583 spmc_ep_info->spsr = SPSR_64(runtime_el, 584 MODE_SP_ELX, 585 DISABLE_ALL_EXCEPTIONS); 586 } 587 588 #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 589 image_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID); 590 assert(image_info != NULL); 591 592 if ((image_info->config_addr == 0UL) || 593 (image_info->secondary_config_addr == 0UL) || 594 (image_info->config_max_size == 0UL)) { 595 return -EINVAL; 596 } 597 598 /* Copy manifest from root->secure region */ 599 spmd_do_sec_cpy(image_info->config_addr, 600 image_info->secondary_config_addr, 601 image_info->config_max_size); 602 603 /* Update ep info of BL32 */ 604 assert(spmc_ep_info != NULL); 605 spmc_ep_info->args.arg0 = image_info->secondary_config_addr; 606 #endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */ 607 608 spmd_setup_context(plat_my_core_pos()); 609 610 /* Register power management hooks with PSCI */ 611 psci_register_spd_pm_hook(&spmd_pm); 612 613 /* Register init function for deferred init. */ 614 bl31_register_bl32_init(&spmd_init); 615 616 INFO("SPM Core setup done.\n"); 617 618 /* 619 * Register an interrupt handler routing secure interrupts to SPMD 620 * while the NWd is running. 621 */ 622 flags = 0; 623 set_interrupt_rm_flag(flags, NON_SECURE); 624 rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 625 spmd_secure_interrupt_handler, 626 flags); 627 if (rc != 0) { 628 panic(); 629 } 630 631 /* 632 * Permit configurations where the SPM resides at S-EL1/2 and upon a 633 * Group0 interrupt triggering while the normal world runs, the 634 * interrupt is routed either through the EHF or directly to the SPMD: 635 * 636 * EL3_EXCEPTION_HANDLING=0: the Group0 interrupt is routed to the SPMD 637 * for handling by spmd_group0_interrupt_handler_nwd. 638 * 639 * EL3_EXCEPTION_HANDLING=1: the Group0 interrupt is routed to the EHF. 640 * 641 */ 642 #if (EL3_EXCEPTION_HANDLING == 0) 643 /* 644 * If EL3 interrupts are supported by the platform, register an 645 * interrupt handler routing Group0 interrupts to SPMD while the NWd is 646 * running. 647 */ 648 if (plat_ic_has_interrupt_type(INTR_TYPE_EL3)) { 649 rc = register_interrupt_type_handler(INTR_TYPE_EL3, 650 spmd_group0_interrupt_handler_nwd, 651 flags); 652 if (rc != 0) { 653 panic(); 654 } 655 } 656 #endif 657 658 return 0; 659 } 660 661 /******************************************************************************* 662 * Initialize context of SPM Core. 663 ******************************************************************************/ 664 int spmd_setup(void) 665 { 666 int rc; 667 void *spmc_manifest; 668 struct transfer_list_header *tl __maybe_unused; 669 struct transfer_list_entry *te __maybe_unused; 670 671 /* 672 * If the SPMC is at EL3, then just initialise it directly. The 673 * shenanigans of when it is at a lower EL are not needed. 674 */ 675 if (is_spmc_at_el3()) { 676 /* Allow the SPMC to populate its attributes directly. */ 677 spmc_populate_attrs(&spmc_attrs); 678 679 rc = spmc_setup(); 680 if (rc != 0) { 681 WARN("SPMC initialisation failed 0x%x.\n", rc); 682 } 683 return 0; 684 } 685 686 spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE); 687 if (spmc_ep_info == NULL) { 688 WARN("No SPM Core image provided by BL2 boot loader.\n"); 689 return 0; 690 } 691 692 /* Under no circumstances will this parameter be 0 */ 693 assert(spmc_ep_info->pc != 0ULL); 694 695 696 #if TRANSFER_LIST && !RESET_TO_BL31 697 tl = (struct transfer_list_header *)spmc_ep_info->args.arg3; 698 te = transfer_list_find(tl, TL_TAG_DT_SPMC_MANIFEST); 699 if (te == NULL) { 700 WARN("SPM Core manifest absent in TRANSFER_LIST.\n"); 701 return -ENOENT; 702 } 703 704 spmc_manifest = (void *)transfer_list_entry_data(te); 705 706 /* Change the DT in the handoff */ 707 if (sizeof(spmc_ep_info->args.arg0) == sizeof(uint64_t)) { 708 spmc_ep_info->args.arg0 = (uintptr_t)spmc_manifest; 709 } else { 710 spmc_ep_info->args.arg3 = (uintptr_t)spmc_manifest; 711 } 712 #else 713 /* 714 * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will 715 * be used as a manifest for the SPM Core at the next lower EL/mode. 716 */ 717 spmc_manifest = (void *)spmc_ep_info->args.arg0; 718 #endif 719 720 if (spmc_manifest == NULL) { 721 WARN("Invalid or absent SPM Core manifest.\n"); 722 return 0; 723 } 724 725 /* Load manifest, init SPMC */ 726 rc = spmd_spmc_init(spmc_manifest); 727 if (rc != 0) { 728 WARN("Booting device without SPM initialization.\n"); 729 } 730 731 return 0; 732 } 733 734 /******************************************************************************* 735 * Forward FF-A SMCs to the other security state. 736 ******************************************************************************/ 737 uint64_t spmd_smc_switch_state(uint32_t smc_fid, 738 bool secure_origin, 739 uint64_t x1, 740 uint64_t x2, 741 uint64_t x3, 742 uint64_t x4, 743 void *handle, 744 uint64_t flags, 745 uint32_t secure_ffa_version) 746 { 747 unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE; 748 unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE; 749 uint32_t version_in = (secure_origin) ? secure_ffa_version : nonsecure_ffa_version; 750 uint32_t version_out = (!secure_origin) ? secure_ffa_version : nonsecure_ffa_version; 751 void *ctx_out; 752 753 #if SPMD_SPM_AT_SEL2 754 if ((secure_state_out == SECURE) && (is_sve_hint_set(flags) == true)) { 755 /* 756 * Set the SVE hint bit in x0 and pass to the lower secure EL, 757 * if it was set by the caller. 758 */ 759 smc_fid |= (FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT); 760 } 761 #endif 762 763 /* Save incoming security state */ 764 #if SPMD_SPM_AT_SEL2 765 cm_el2_sysregs_context_save(secure_state_in); 766 #else 767 cm_el1_sysregs_context_save(secure_state_in); 768 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS 769 /* Forward the hint bit denoting the absence of SVE live state. */ 770 simd_ctx_save(secure_state_in, (!secure_origin && (is_sve_hint_set(flags) == true))); 771 #endif 772 #endif 773 774 /* Restore outgoing security state */ 775 #if SPMD_SPM_AT_SEL2 776 cm_el2_sysregs_context_restore(secure_state_out); 777 #else 778 cm_el1_sysregs_context_restore(secure_state_out); 779 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS 780 simd_ctx_restore(secure_state_out); 781 #endif 782 #endif 783 cm_set_next_eret_context(secure_state_out); 784 785 ctx_out = cm_get_context(secure_state_out); 786 if (smc_fid == FFA_NORMAL_WORLD_RESUME) { 787 SMC_RET0(ctx_out); 788 } 789 790 if ((GET_SMC_CC(smc_fid) == SMC_64) && (version_out >= MAKE_FFA_VERSION(U(1), U(2)))) { 791 if (version_in < MAKE_FFA_VERSION(U(1), U(2))) { 792 /* FFA version mismatch, with dest >= 1.2 - set outgoing x8-x17 to zero */ 793 SMC_RET18(ctx_out, smc_fid, x1, x2, x3, x4, 794 SMC_GET_GP(handle, CTX_GPREG_X5), 795 SMC_GET_GP(handle, CTX_GPREG_X6), 796 SMC_GET_GP(handle, CTX_GPREG_X7), 797 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 798 } else { 799 /* Both FFA versions >= 1.2 - pass incoming x8-x17 to dest */ 800 SMC_RET18(ctx_out, smc_fid, x1, x2, x3, x4, 801 SMC_GET_GP(handle, CTX_GPREG_X5), 802 SMC_GET_GP(handle, CTX_GPREG_X6), 803 SMC_GET_GP(handle, CTX_GPREG_X7), 804 SMC_GET_GP(handle, CTX_GPREG_X8), 805 SMC_GET_GP(handle, CTX_GPREG_X9), 806 SMC_GET_GP(handle, CTX_GPREG_X10), 807 SMC_GET_GP(handle, CTX_GPREG_X11), 808 SMC_GET_GP(handle, CTX_GPREG_X12), 809 SMC_GET_GP(handle, CTX_GPREG_X13), 810 SMC_GET_GP(handle, CTX_GPREG_X14), 811 SMC_GET_GP(handle, CTX_GPREG_X15), 812 SMC_GET_GP(handle, CTX_GPREG_X16), 813 SMC_GET_GP(handle, CTX_GPREG_X17) 814 ); 815 } 816 } else { 817 /* 32 bit call or dest has FFA version < 1.2 or unknown */ 818 SMC_RET8(ctx_out, smc_fid, x1, x2, x3, x4, 819 SMC_GET_GP(handle, CTX_GPREG_X5), 820 SMC_GET_GP(handle, CTX_GPREG_X6), 821 SMC_GET_GP(handle, CTX_GPREG_X7)); 822 } 823 } 824 825 /******************************************************************************* 826 * Forward SMCs to the other security state. 827 ******************************************************************************/ 828 static uint64_t spmd_smc_forward(uint32_t smc_fid, 829 bool secure_origin, 830 uint64_t x1, 831 uint64_t x2, 832 uint64_t x3, 833 uint64_t x4, 834 void *cookie, 835 void *handle, 836 uint64_t flags, 837 uint32_t secure_ffa_version) 838 { 839 if (is_spmc_at_el3() && !secure_origin) { 840 return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4, 841 cookie, handle, flags); 842 } 843 844 return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4, 845 handle, flags, secure_ffa_version); 846 847 } 848 849 /******************************************************************************* 850 * Return FFA_ERROR with specified error code 851 ******************************************************************************/ 852 uint64_t spmd_ffa_error_return(void *handle, int error_code) 853 { 854 SMC_RET8(handle, (uint32_t) FFA_ERROR, 855 FFA_TARGET_INFO_MBZ, (uint32_t)error_code, 856 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 857 FFA_PARAM_MBZ, FFA_PARAM_MBZ); 858 } 859 860 /******************************************************************************* 861 * spmd_check_address_in_binary_image 862 ******************************************************************************/ 863 bool spmd_check_address_in_binary_image(uint64_t address) 864 { 865 assert(!check_uptr_overflow(spmc_attrs.load_address, spmc_attrs.binary_size)); 866 867 return ((address >= spmc_attrs.load_address) && 868 (address < (spmc_attrs.load_address + spmc_attrs.binary_size))); 869 } 870 871 /****************************************************************************** 872 * spmd_is_spmc_message 873 *****************************************************************************/ 874 static bool spmd_is_spmc_message(unsigned int ep) 875 { 876 if (is_spmc_at_el3()) { 877 return false; 878 } 879 880 return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID) 881 && (ffa_endpoint_source(ep) == spmc_attrs.spmc_id)); 882 } 883 884 /******************************************************************************* 885 * This function forwards FF-A SMCs to either the main SPMD handler or the 886 * SPMC at EL3, depending on the origin security state, if enabled. 887 ******************************************************************************/ 888 uint64_t spmd_ffa_smc_handler(uint32_t smc_fid, 889 uint64_t x1, 890 uint64_t x2, 891 uint64_t x3, 892 uint64_t x4, 893 void *cookie, 894 void *handle, 895 uint64_t flags) 896 { 897 if (is_spmc_at_el3()) { 898 /* 899 * If we have an SPMC at EL3 allow handling of the SMC first. 900 * The SPMC will call back through to SPMD handler if required. 901 */ 902 if (is_caller_secure(flags)) { 903 return spmc_smc_handler(smc_fid, 904 is_caller_secure(flags), 905 x1, x2, x3, x4, cookie, 906 handle, flags); 907 } 908 } 909 return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 910 handle, flags, spmc_nwd_ffa_version); 911 } 912 913 static uint32_t get_common_ffa_version(uint32_t secure_ffa_version) 914 { 915 if (secure_ffa_version <= nonsecure_ffa_version) { 916 return secure_ffa_version; 917 } else { 918 return nonsecure_ffa_version; 919 } 920 } 921 922 /******************************************************************************* 923 * This function handles all SMCs in the range reserved for FFA. Each call is 924 * either forwarded to the other security state or handled by the SPM dispatcher 925 ******************************************************************************/ 926 uint64_t spmd_smc_handler(uint32_t smc_fid, 927 uint64_t x1, 928 uint64_t x2, 929 uint64_t x3, 930 uint64_t x4, 931 void *cookie, 932 void *handle, 933 uint64_t flags, 934 uint32_t secure_ffa_version) 935 { 936 spmd_spm_core_context_t *ctx = spmd_get_context(); 937 bool secure_origin; 938 int ret; 939 uint32_t input_version; 940 941 /* Determine which security state this SMC originated from */ 942 secure_origin = is_caller_secure(flags); 943 944 VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 945 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n", 946 plat_my_core_pos(), smc_fid, x1, x2, x3, x4, 947 SMC_GET_GP(handle, CTX_GPREG_X5), 948 SMC_GET_GP(handle, CTX_GPREG_X6), 949 SMC_GET_GP(handle, CTX_GPREG_X7)); 950 951 /* 952 * If there is an on-going info regs from EL3 SPMD LP, unconditionally 953 * return, we don't expect any other FF-A ABIs to be called between 954 * calls to FFA_PARTITION_INFO_GET_REGS. 955 */ 956 if (is_spmd_logical_sp_info_regs_req_in_progress(ctx)) { 957 assert(secure_origin); 958 spmd_spm_core_sync_exit(0ULL); 959 } 960 961 if ((!secure_origin) && (smc_fid != FFA_VERSION)) { 962 /* 963 * Once the caller invokes any FF-A ABI other than FFA_VERSION, 964 * the version negotiation phase is complete. 965 */ 966 nonsecure_version_negotiated = true; 967 } 968 969 switch (smc_fid) { 970 case FFA_ERROR: 971 /* 972 * Check if this is the first invocation of this interface on 973 * this CPU. If so, then indicate that the SPM Core initialised 974 * unsuccessfully. 975 */ 976 if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) { 977 spmd_spm_core_sync_exit(x2); 978 } 979 980 /* 981 * Perform a synchronous exit: 982 * 1. If there was an SPMD logical partition direct request on-going, 983 * return back to the SPMD logical partition so the error can be 984 * consumed. 985 * 2. SPMC sent FFA_ERROR in response to a power management 986 * operation sent through direct request. 987 */ 988 if (is_spmd_logical_sp_dir_req_in_progress(ctx) || 989 ctx->psci_operation_ongoing) { 990 assert(secure_origin); 991 spmd_spm_core_sync_exit(0ULL); 992 } 993 994 return spmd_smc_forward(smc_fid, secure_origin, 995 x1, x2, x3, x4, cookie, 996 handle, flags, secure_ffa_version); 997 break; /* not reached */ 998 999 case FFA_VERSION: 1000 input_version = (uint32_t)(0xFFFFFFFF & x1); 1001 /* 1002 * If caller is secure and SPMC was initialized, 1003 * return FFA_VERSION of SPMD. 1004 * If caller is non secure and SPMC was initialized, 1005 * forward to the EL3 SPMC if enabled, otherwise send a 1006 * framework message to the SPMC at the lower EL to 1007 * negotiate a version that is compatible between the 1008 * normal world and the SPMC. 1009 * Sanity check to "input_version". 1010 * If the EL3 SPMC is enabled, ignore the SPMC state as 1011 * this is not used. 1012 */ 1013 if ((input_version & FFA_VERSION_BIT31_MASK) || 1014 (!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) { 1015 ret = FFA_ERROR_NOT_SUPPORTED; 1016 } else if (!secure_origin) { 1017 if (!nonsecure_version_negotiated) { 1018 /* 1019 * Once an FF-A version has been negotiated 1020 * between a caller and a callee, the version 1021 * may not be changed for the lifetime of 1022 * the calling component. 1023 */ 1024 nonsecure_ffa_version = input_version; 1025 } 1026 1027 if (is_spmc_at_el3()) { 1028 /* 1029 * Forward the call directly to the EL3 SPMC, if 1030 * enabled, as we don't need to wrap the call in 1031 * a direct request. 1032 */ 1033 spmc_nwd_ffa_version = 1034 MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR); 1035 return spmc_smc_handler(smc_fid, secure_origin, 1036 x1, x2, x3, x4, cookie, 1037 handle, flags); 1038 } 1039 1040 gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx); 1041 uint64_t rc; 1042 1043 if (spmc_attrs.major_version == 1 && 1044 spmc_attrs.minor_version == 0) { 1045 ret = MAKE_FFA_VERSION(spmc_attrs.major_version, 1046 spmc_attrs.minor_version); 1047 spmc_nwd_ffa_version = (uint32_t)ret; 1048 SMC_RET8(handle, (uint32_t)ret, 1049 FFA_TARGET_INFO_MBZ, 1050 FFA_TARGET_INFO_MBZ, 1051 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1052 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1053 FFA_PARAM_MBZ); 1054 break; 1055 } 1056 /* Save non-secure system registers context */ 1057 #if SPMD_SPM_AT_SEL2 1058 cm_el2_sysregs_context_save(NON_SECURE); 1059 #else 1060 cm_el1_sysregs_context_save(NON_SECURE); 1061 #endif 1062 1063 /* 1064 * The incoming request has FFA_VERSION as X0 smc_fid 1065 * and requested version in x1. Prepare a direct request 1066 * from SPMD to SPMC with FFA_VERSION framework function 1067 * identifier in X2 and requested version in X3. 1068 */ 1069 spmd_build_spmc_message(gpregs, 1070 SPMD_FWK_MSG_FFA_VERSION_REQ, 1071 input_version); 1072 1073 /* 1074 * Ensure x8-x17 NS GP register values are untouched when returning 1075 * from the SPMC. 1076 */ 1077 write_ctx_reg(gpregs, CTX_GPREG_X8, SMC_GET_GP(handle, CTX_GPREG_X8)); 1078 write_ctx_reg(gpregs, CTX_GPREG_X9, SMC_GET_GP(handle, CTX_GPREG_X9)); 1079 write_ctx_reg(gpregs, CTX_GPREG_X10, SMC_GET_GP(handle, CTX_GPREG_X10)); 1080 write_ctx_reg(gpregs, CTX_GPREG_X11, SMC_GET_GP(handle, CTX_GPREG_X11)); 1081 write_ctx_reg(gpregs, CTX_GPREG_X12, SMC_GET_GP(handle, CTX_GPREG_X12)); 1082 write_ctx_reg(gpregs, CTX_GPREG_X13, SMC_GET_GP(handle, CTX_GPREG_X13)); 1083 write_ctx_reg(gpregs, CTX_GPREG_X14, SMC_GET_GP(handle, CTX_GPREG_X14)); 1084 write_ctx_reg(gpregs, CTX_GPREG_X15, SMC_GET_GP(handle, CTX_GPREG_X15)); 1085 write_ctx_reg(gpregs, CTX_GPREG_X16, SMC_GET_GP(handle, CTX_GPREG_X16)); 1086 write_ctx_reg(gpregs, CTX_GPREG_X17, SMC_GET_GP(handle, CTX_GPREG_X17)); 1087 1088 rc = spmd_spm_core_sync_entry(ctx); 1089 1090 if ((rc != 0ULL) || 1091 (SMC_GET_GP(gpregs, CTX_GPREG_X0) != 1092 FFA_MSG_SEND_DIRECT_RESP_SMC32) || 1093 (SMC_GET_GP(gpregs, CTX_GPREG_X2) != 1094 (FFA_FWK_MSG_BIT | 1095 SPMD_FWK_MSG_FFA_VERSION_RESP))) { 1096 ERROR("Failed to forward FFA_VERSION\n"); 1097 ret = FFA_ERROR_NOT_SUPPORTED; 1098 } else { 1099 ret = SMC_GET_GP(gpregs, CTX_GPREG_X3); 1100 spmc_nwd_ffa_version = (uint32_t)ret; 1101 } 1102 1103 /* 1104 * x0-x4 are updated by spmd_smc_forward below. 1105 * Zero out x5-x7 in the FFA_VERSION response. 1106 */ 1107 write_ctx_reg(gpregs, CTX_GPREG_X5, 0); 1108 write_ctx_reg(gpregs, CTX_GPREG_X6, 0); 1109 write_ctx_reg(gpregs, CTX_GPREG_X7, 0); 1110 1111 /* 1112 * Return here after SPMC has handled FFA_VERSION. 1113 * The returned SPMC version is held in X3. 1114 * Forward this version in X0 to the non-secure caller. 1115 */ 1116 return spmd_smc_forward(ret, true, FFA_PARAM_MBZ, 1117 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1118 FFA_PARAM_MBZ, cookie, gpregs, 1119 flags, spmc_nwd_ffa_version); 1120 } else { 1121 ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR, 1122 FFA_VERSION_MINOR); 1123 } 1124 1125 SMC_RET8(handle, (uint32_t)ret, FFA_TARGET_INFO_MBZ, 1126 FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1127 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ); 1128 break; /* not reached */ 1129 1130 case FFA_FEATURES: 1131 /* 1132 * This is an optional interface. Do the minimal checks and 1133 * forward to SPM Core which will handle it if implemented. 1134 */ 1135 1136 /* Forward SMC from Normal world to the SPM Core */ 1137 if (!secure_origin) { 1138 return spmd_smc_forward(smc_fid, secure_origin, 1139 x1, x2, x3, x4, cookie, 1140 handle, flags, secure_ffa_version); 1141 } 1142 1143 /* 1144 * Return success if call was from secure world i.e. all 1145 * FFA functions are supported. This is essentially a 1146 * nop. 1147 */ 1148 SMC_RET8(handle, FFA_SUCCESS_SMC32, x1, x2, x3, x4, 1149 SMC_GET_GP(handle, CTX_GPREG_X5), 1150 SMC_GET_GP(handle, CTX_GPREG_X6), 1151 SMC_GET_GP(handle, CTX_GPREG_X7)); 1152 1153 break; /* not reached */ 1154 1155 case FFA_ID_GET: 1156 /* 1157 * Returns the ID of the calling FFA component. 1158 */ 1159 if (!secure_origin) { 1160 SMC_RET8(handle, FFA_SUCCESS_SMC32, 1161 FFA_TARGET_INFO_MBZ, FFA_NS_ENDPOINT_ID, 1162 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1163 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1164 FFA_PARAM_MBZ); 1165 } 1166 1167 SMC_RET8(handle, FFA_SUCCESS_SMC32, 1168 FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id, 1169 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1170 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1171 FFA_PARAM_MBZ); 1172 1173 break; /* not reached */ 1174 1175 case FFA_SECONDARY_EP_REGISTER_SMC64: 1176 if (secure_origin) { 1177 ret = spmd_pm_secondary_ep_register(x1); 1178 1179 if (ret < 0) { 1180 SMC_RET8(handle, FFA_ERROR_SMC64, 1181 FFA_TARGET_INFO_MBZ, ret, 1182 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1183 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1184 FFA_PARAM_MBZ); 1185 } else { 1186 SMC_RET8(handle, FFA_SUCCESS_SMC64, 1187 FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ, 1188 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1189 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1190 FFA_PARAM_MBZ); 1191 } 1192 } 1193 1194 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1195 break; /* Not reached */ 1196 1197 case FFA_SPM_ID_GET: 1198 if (MAKE_FFA_VERSION(1, 1) > FFA_VERSION_COMPILED) { 1199 return spmd_ffa_error_return(handle, 1200 FFA_ERROR_NOT_SUPPORTED); 1201 } 1202 /* 1203 * Returns the ID of the SPMC or SPMD depending on the FF-A 1204 * instance where this function is invoked 1205 */ 1206 if (!secure_origin) { 1207 SMC_RET8(handle, FFA_SUCCESS_SMC32, 1208 FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id, 1209 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1210 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1211 FFA_PARAM_MBZ); 1212 } 1213 SMC_RET8(handle, FFA_SUCCESS_SMC32, 1214 FFA_TARGET_INFO_MBZ, SPMD_DIRECT_MSG_ENDPOINT_ID, 1215 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1216 FFA_PARAM_MBZ, FFA_PARAM_MBZ, 1217 FFA_PARAM_MBZ); 1218 1219 break; /* not reached */ 1220 1221 case FFA_MSG_SEND_DIRECT_REQ2_SMC64: 1222 if (get_common_ffa_version(secure_ffa_version) < MAKE_FFA_VERSION(U(1), U(2))) { 1223 /* Call not supported at this version */ 1224 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1225 } 1226 /* fallthrough */ 1227 case FFA_MSG_SEND_DIRECT_REQ_SMC32: 1228 case FFA_MSG_SEND_DIRECT_REQ_SMC64: 1229 /* 1230 * Regardless of secure_origin, SPMD logical partitions cannot 1231 * handle direct messages. They can only initiate direct 1232 * messages and consume direct responses or errors. 1233 */ 1234 if (is_spmd_lp_id(ffa_endpoint_source(x1)) || 1235 is_spmd_lp_id(ffa_endpoint_destination(x1))) { 1236 return spmd_ffa_error_return(handle, 1237 FFA_ERROR_INVALID_PARAMETER 1238 ); 1239 } 1240 1241 /* 1242 * When there is an ongoing SPMD logical partition direct 1243 * request, there cannot be another direct request. Return 1244 * error in this case. Panic'ing is an option but that does 1245 * not provide the opportunity for caller to abort based on 1246 * error codes. 1247 */ 1248 if (is_spmd_logical_sp_dir_req_in_progress(ctx)) { 1249 assert(secure_origin); 1250 return spmd_ffa_error_return(handle, 1251 FFA_ERROR_DENIED); 1252 } 1253 1254 if (!secure_origin) { 1255 /* Validate source endpoint is non-secure for non-secure caller. */ 1256 if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) { 1257 return spmd_ffa_error_return(handle, 1258 FFA_ERROR_INVALID_PARAMETER); 1259 } 1260 } 1261 if (secure_origin && spmd_is_spmc_message(x1)) { 1262 return spmd_ffa_error_return(handle, 1263 FFA_ERROR_DENIED); 1264 } else { 1265 /* Forward direct message to the other world */ 1266 return spmd_smc_forward(smc_fid, secure_origin, 1267 x1, x2, x3, x4, cookie, 1268 handle, flags, secure_ffa_version); 1269 } 1270 break; /* Not reached */ 1271 1272 case FFA_MSG_SEND_DIRECT_RESP2_SMC64: 1273 if (get_common_ffa_version(secure_ffa_version) < MAKE_FFA_VERSION(U(1), U(2))) { 1274 /* Call not supported at this version */ 1275 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1276 } 1277 /* fallthrough */ 1278 case FFA_MSG_SEND_DIRECT_RESP_SMC32: 1279 case FFA_MSG_SEND_DIRECT_RESP_SMC64: 1280 if (secure_origin && (spmd_is_spmc_message(x1) || 1281 is_spmd_logical_sp_dir_req_in_progress(ctx))) { 1282 spmd_spm_core_sync_exit(0ULL); 1283 } else { 1284 /* Forward direct message to the other world */ 1285 return spmd_smc_forward(smc_fid, secure_origin, 1286 x1, x2, x3, x4, cookie, 1287 handle, flags, secure_ffa_version); 1288 } 1289 break; /* Not reached */ 1290 case FFA_RX_RELEASE: 1291 case FFA_RXTX_MAP_SMC32: 1292 case FFA_RXTX_MAP_SMC64: 1293 case FFA_RXTX_UNMAP: 1294 case FFA_PARTITION_INFO_GET: 1295 #if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED 1296 case FFA_NOTIFICATION_BITMAP_CREATE: 1297 case FFA_NOTIFICATION_BITMAP_DESTROY: 1298 case FFA_NOTIFICATION_BIND: 1299 case FFA_NOTIFICATION_UNBIND: 1300 case FFA_NOTIFICATION_SET: 1301 case FFA_NOTIFICATION_GET: 1302 case FFA_NOTIFICATION_INFO_GET: 1303 case FFA_NOTIFICATION_INFO_GET_SMC64: 1304 case FFA_MSG_SEND2: 1305 case FFA_RX_ACQUIRE: 1306 case FFA_NS_RES_INFO_GET_SMC64: 1307 #endif 1308 case FFA_MSG_RUN: 1309 /* 1310 * Above calls should be invoked only by the Normal world and 1311 * must not be forwarded from Secure world to Normal world. 1312 */ 1313 if (secure_origin) { 1314 return spmd_ffa_error_return(handle, 1315 FFA_ERROR_NOT_SUPPORTED); 1316 } 1317 1318 /* Forward the call to the other world */ 1319 /* fallthrough */ 1320 case FFA_MSG_SEND: 1321 case FFA_MEM_DONATE_SMC32: 1322 case FFA_MEM_DONATE_SMC64: 1323 case FFA_MEM_LEND_SMC32: 1324 case FFA_MEM_LEND_SMC64: 1325 case FFA_MEM_SHARE_SMC32: 1326 case FFA_MEM_SHARE_SMC64: 1327 case FFA_MEM_RETRIEVE_REQ_SMC32: 1328 case FFA_MEM_RETRIEVE_REQ_SMC64: 1329 case FFA_MEM_RETRIEVE_RESP: 1330 case FFA_MEM_RELINQUISH: 1331 case FFA_MEM_RECLAIM: 1332 case FFA_MEM_FRAG_TX: 1333 case FFA_MEM_FRAG_RX: 1334 case FFA_SUCCESS_SMC32: 1335 case FFA_SUCCESS_SMC64: 1336 /* 1337 * If there is an ongoing direct request from an SPMD logical 1338 * partition, return an error. 1339 */ 1340 if (is_spmd_logical_sp_dir_req_in_progress(ctx)) { 1341 assert(secure_origin); 1342 return spmd_ffa_error_return(handle, 1343 FFA_ERROR_DENIED); 1344 } 1345 1346 return spmd_smc_forward(smc_fid, secure_origin, 1347 x1, x2, x3, x4, cookie, 1348 handle, flags, secure_ffa_version); 1349 break; /* not reached */ 1350 1351 case FFA_MSG_WAIT: 1352 /* 1353 * Check if this is the first invocation of this interface on 1354 * this CPU from the Secure world. If so, then indicate that the 1355 * SPM Core initialised successfully. 1356 */ 1357 if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) { 1358 spmd_spm_core_sync_exit(0ULL); 1359 } 1360 1361 /* Forward the call to the other world */ 1362 /* fallthrough */ 1363 case FFA_INTERRUPT: 1364 case FFA_MSG_YIELD: 1365 /* This interface must be invoked only by the Secure world */ 1366 if (!secure_origin) { 1367 return spmd_ffa_error_return(handle, 1368 FFA_ERROR_NOT_SUPPORTED); 1369 } 1370 1371 if (is_spmd_logical_sp_dir_req_in_progress(ctx)) { 1372 assert(secure_origin); 1373 return spmd_ffa_error_return(handle, 1374 FFA_ERROR_DENIED); 1375 } 1376 1377 return spmd_smc_forward(smc_fid, secure_origin, 1378 x1, x2, x3, x4, cookie, 1379 handle, flags, secure_ffa_version); 1380 break; /* not reached */ 1381 1382 case FFA_NORMAL_WORLD_RESUME: 1383 if (secure_origin && ctx->secure_interrupt_ongoing) { 1384 spmd_spm_core_sync_exit(0ULL); 1385 } else { 1386 return spmd_ffa_error_return(handle, FFA_ERROR_DENIED); 1387 } 1388 break; /* Not reached */ 1389 #if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED 1390 case FFA_PARTITION_INFO_GET_REGS_SMC64: 1391 if (secure_origin) { 1392 return spmd_el3_populate_logical_partition_info(handle, x1, 1393 x2, x3); 1394 } 1395 1396 /* Call only supported with SMCCC 1.2+ */ 1397 if (MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION) < 0x10002) { 1398 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1399 } 1400 1401 return spmd_smc_forward(smc_fid, secure_origin, 1402 x1, x2, x3, x4, cookie, 1403 handle, flags, secure_ffa_version); 1404 break; /* Not reached */ 1405 #endif 1406 case FFA_CONSOLE_LOG_SMC32: 1407 case FFA_CONSOLE_LOG_SMC64: 1408 /* This interface must not be forwarded to other worlds. */ 1409 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1410 break; /* not reached */ 1411 1412 case FFA_EL3_INTR_HANDLE: 1413 if (secure_origin) { 1414 return spmd_handle_group0_intr_swd(handle); 1415 } else { 1416 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1417 } 1418 case FFA_ABORT_SMC32: 1419 case FFA_ABORT_SMC64: 1420 /* This interface must be invoked only by the Secure world */ 1421 if (!secure_origin) { 1422 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1423 } 1424 1425 ERROR("SPMC encountered a fatal error. Aborting now\n"); 1426 panic(); 1427 1428 /* Not reached. */ 1429 SMC_RET0(handle); 1430 default: 1431 WARN("SPM: Unsupported call 0x%08x\n", smc_fid); 1432 return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 1433 } 1434 } 1435