1 /* 2 * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <arch.h> 11 #include <arch_helpers.h> 12 #include <common/debug.h> 13 #include <common/fdt_wrappers.h> 14 #include <context.h> 15 #include <lib/el3_runtime/context_mgmt.h> 16 #include <lib/utils.h> 17 #include <lib/xlat_tables/xlat_tables_v2.h> 18 #include <libfdt.h> 19 #include <plat/common/common_def.h> 20 #include <plat/common/platform.h> 21 #include <services/ffa_svc.h> 22 #include "spm_common.h" 23 #include "spm_shim_private.h" 24 #include "spmc.h" 25 #include <tools_share/firmware_image_package.h> 26 27 #include <platform_def.h> 28 29 /* 30 * Statically allocate a page of memory for passing boot information to an SP. 31 */ 32 static uint8_t ffa_boot_info_mem[PAGE_SIZE] __aligned(PAGE_SIZE); 33 34 /* 35 * We need to choose one execution context from all those available for a S-EL0 36 * SP. This execution context will be used subsequently irrespective of which 37 * physical CPU the SP runs on. 38 */ 39 #define SEL0_SP_EC_INDEX 0 40 #define SP_MEM_READ 0x1 41 #define SP_MEM_WRITE 0x2 42 #define SP_MEM_EXECUTE 0x4 43 #define SP_MEM_NON_SECURE 0x8 44 #define SP_MEM_READ_ONLY SP_MEM_READ 45 #define SP_MEM_READ_WRITE (SP_MEM_READ | SP_MEM_WRITE) 46 47 /* Type of the memory region in SP's manifest. */ 48 enum sp_memory_region_type { 49 SP_MEM_REGION_DEVICE, 50 SP_MEM_REGION_MEMORY, 51 SP_MEM_REGION_NOT_SPECIFIED 52 }; 53 54 /* 55 * This function creates a initialization descriptor in the memory reserved 56 * for passing boot information to an SP. It then copies the partition manifest 57 * into this region and ensures that its reference in the initialization 58 * descriptor is updated. 59 */ 60 static void spmc_create_boot_info(entry_point_info_t *ep_info, 61 struct secure_partition_desc *sp) 62 { 63 struct ffa_boot_info_header *boot_header; 64 struct ffa_boot_info_desc *boot_descriptor; 65 uintptr_t manifest_addr; 66 67 /* 68 * Calculate the maximum size of the manifest that can be accommodated 69 * in the boot information memory region. 70 */ 71 const unsigned int 72 max_manifest_sz = sizeof(ffa_boot_info_mem) - 73 (sizeof(struct ffa_boot_info_header) + 74 sizeof(struct ffa_boot_info_desc)); 75 76 /* 77 * The current implementation only supports the FF-A v1.1 78 * implementation of the boot protocol, therefore check 79 * that a v1.0 SP has not requested use of the protocol. 80 */ 81 if (sp->ffa_version == MAKE_FFA_VERSION(1, 0)) { 82 ERROR("FF-A boot protocol not supported for v1.0 clients\n"); 83 return; 84 } 85 86 /* 87 * Check if the manifest will fit into the boot info memory region else 88 * bail. 89 */ 90 if (ep_info->args.arg1 > max_manifest_sz) { 91 WARN("Unable to copy manifest into boot information. "); 92 WARN("Max sz = %u bytes. Manifest sz = %lu bytes\n", 93 max_manifest_sz, ep_info->args.arg1); 94 return; 95 } 96 97 /* Zero the memory region before populating. */ 98 memset(ffa_boot_info_mem, 0, PAGE_SIZE); 99 100 /* 101 * Populate the ffa_boot_info_header at the start of the boot info 102 * region. 103 */ 104 boot_header = (struct ffa_boot_info_header *) ffa_boot_info_mem; 105 106 /* Position the ffa_boot_info_desc after the ffa_boot_info_header. */ 107 boot_header->offset_boot_info_desc = 108 sizeof(struct ffa_boot_info_header); 109 boot_descriptor = (struct ffa_boot_info_desc *) 110 (ffa_boot_info_mem + 111 boot_header->offset_boot_info_desc); 112 113 /* 114 * We must use the FF-A version corresponding to the version implemented 115 * by the SP. Currently this can only be v1.1. 116 */ 117 boot_header->version = sp->ffa_version; 118 119 /* Populate the boot information header. */ 120 boot_header->size_boot_info_desc = sizeof(struct ffa_boot_info_desc); 121 122 /* Set the signature "0xFFA". */ 123 boot_header->signature = FFA_INIT_DESC_SIGNATURE; 124 125 /* Set the count. Currently 1 since only the manifest is specified. */ 126 boot_header->count_boot_info_desc = 1; 127 128 /* Populate the boot information descriptor for the manifest. */ 129 boot_descriptor->type = 130 FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) | 131 FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT); 132 133 boot_descriptor->flags = 134 FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) | 135 FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR); 136 137 /* 138 * Copy the manifest into boot info region after the boot information 139 * descriptor. 140 */ 141 boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1; 142 143 manifest_addr = (uintptr_t) (ffa_boot_info_mem + 144 boot_header->offset_boot_info_desc + 145 boot_header->size_boot_info_desc); 146 147 memcpy((void *) manifest_addr, (void *) ep_info->args.arg0, 148 boot_descriptor->size_boot_info); 149 150 boot_descriptor->content = manifest_addr; 151 152 /* Calculate the size of the total boot info blob. */ 153 boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc + 154 boot_descriptor->size_boot_info + 155 (boot_header->count_boot_info_desc * 156 boot_header->size_boot_info_desc); 157 158 INFO("SP boot info @ 0x%lx, size: %u bytes.\n", 159 (uintptr_t) ffa_boot_info_mem, 160 boot_header->size_boot_info_blob); 161 INFO("SP manifest @ 0x%lx, size: %u bytes.\n", 162 boot_descriptor->content, 163 boot_descriptor->size_boot_info); 164 } 165 166 /* 167 * S-EL1 partitions can be assigned with multiple execution contexts, each 168 * pinned to the physical CPU. Each execution context index corresponds to the 169 * respective liner core position. 170 * S-EL0 partitions execute in a single execution context (index 0). 171 */ 172 unsigned int get_ec_index(struct secure_partition_desc *sp) 173 { 174 return (sp->runtime_el == S_EL0) ? 175 SEL0_SP_EC_INDEX : plat_my_core_pos(); 176 } 177 178 #if SPMC_AT_EL3_SEL0_SP 179 /* Setup spsr in entry point info for common context management code to use. */ 180 void spmc_el0_sp_spsr_setup(entry_point_info_t *ep_info) 181 { 182 /* Setup Secure Partition SPSR for S-EL0 SP. */ 183 ep_info->spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS); 184 } 185 186 static void read_optional_string(void *manifest, int32_t offset, 187 char *property, char *out, size_t len) 188 { 189 const fdt32_t *prop; 190 int lenp; 191 192 prop = fdt_getprop(manifest, offset, property, &lenp); 193 if (prop == NULL) { 194 out[0] = '\0'; 195 } else { 196 memcpy(out, prop, MIN(lenp, (int)len)); 197 } 198 } 199 200 /******************************************************************************* 201 * This function will parse the Secure Partition Manifest for fetching secure 202 * partition specific memory/device region details. It will find base address, 203 * size, memory attributes for each region and then add the respective region 204 * into secure parition's translation context. 205 ******************************************************************************/ 206 static void populate_sp_regions(struct secure_partition_desc *sp, 207 void *sp_manifest, int node, 208 enum sp_memory_region_type type) 209 { 210 uintptr_t base_address; 211 uint32_t mem_attr, mem_region, size; 212 struct mmap_region sp_mem_regions = {0}; 213 int32_t offset, ret; 214 char *compatibility[SP_MEM_REGION_NOT_SPECIFIED] = { 215 "arm,ffa-manifest-device-regions", 216 "arm,ffa-manifest-memory-regions" 217 }; 218 char description[10]; 219 char *property; 220 char *region[SP_MEM_REGION_NOT_SPECIFIED] = { 221 "device regions", 222 "memory regions" 223 }; 224 225 if (type >= SP_MEM_REGION_NOT_SPECIFIED) { 226 WARN("Invalid region type\n"); 227 return; 228 } 229 230 INFO("Mapping SP's %s\n", region[type]); 231 232 if (fdt_node_check_compatible(sp_manifest, node, 233 compatibility[type]) != 0) { 234 WARN("Incompatible region node in manifest\n"); 235 return; 236 } 237 238 for (offset = fdt_first_subnode(sp_manifest, node), mem_region = 0; 239 offset >= 0; 240 offset = fdt_next_subnode(sp_manifest, offset), mem_region++) { 241 read_optional_string(sp_manifest, offset, "description", 242 description, sizeof(description)); 243 244 INFO("Mapping: region: %d, %s\n", mem_region, description); 245 246 property = "base-address"; 247 ret = fdt_read_uint64(sp_manifest, offset, property, 248 &base_address); 249 if (ret < 0) { 250 WARN("Missing:%s for %s.\n", property, description); 251 continue; 252 } 253 254 property = "pages-count"; 255 ret = fdt_read_uint32(sp_manifest, offset, property, &size); 256 if (ret < 0) { 257 WARN("Missing: %s for %s.\n", property, description); 258 continue; 259 } 260 size *= PAGE_SIZE; 261 262 property = "attributes"; 263 ret = fdt_read_uint32(sp_manifest, offset, property, &mem_attr); 264 if (ret < 0) { 265 WARN("Missing: %s for %s.\n", property, description); 266 continue; 267 } 268 269 sp_mem_regions.attr = MT_USER; 270 if (type == SP_MEM_REGION_DEVICE) { 271 sp_mem_regions.attr |= MT_EXECUTE_NEVER; 272 } else { 273 sp_mem_regions.attr |= MT_MEMORY; 274 if ((mem_attr & SP_MEM_EXECUTE) == SP_MEM_EXECUTE) { 275 sp_mem_regions.attr &= ~MT_EXECUTE_NEVER; 276 } else { 277 sp_mem_regions.attr |= MT_EXECUTE_NEVER; 278 } 279 } 280 281 if ((mem_attr & SP_MEM_READ_WRITE) == SP_MEM_READ_WRITE) { 282 sp_mem_regions.attr |= MT_RW; 283 } 284 285 if ((mem_attr & SP_MEM_NON_SECURE) == SP_MEM_NON_SECURE) { 286 sp_mem_regions.attr |= MT_NS; 287 } else { 288 sp_mem_regions.attr |= MT_SECURE; 289 } 290 291 sp_mem_regions.base_pa = base_address; 292 sp_mem_regions.base_va = base_address; 293 sp_mem_regions.size = size; 294 295 INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n", 296 sp_mem_regions.base_pa, 297 sp_mem_regions.base_va, 298 sp_mem_regions.size, 299 sp_mem_regions.attr); 300 301 if (type == SP_MEM_REGION_DEVICE) { 302 sp_mem_regions.granularity = XLAT_BLOCK_SIZE(1); 303 } else { 304 sp_mem_regions.granularity = XLAT_BLOCK_SIZE(3); 305 } 306 mmap_add_region_ctx(sp->xlat_ctx_handle, &sp_mem_regions); 307 } 308 } 309 310 static void spmc_el0_sp_setup_mmu(struct secure_partition_desc *sp, 311 cpu_context_t *ctx) 312 { 313 xlat_ctx_t *xlat_ctx; 314 uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; 315 316 xlat_ctx = sp->xlat_ctx_handle; 317 init_xlat_tables_ctx(sp->xlat_ctx_handle); 318 setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table, 319 xlat_ctx->pa_max_address, xlat_ctx->va_max_address, 320 EL1_EL0_REGIME); 321 322 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1, 323 mmu_cfg_params[MMU_CFG_MAIR]); 324 325 /* Store the initialised SCTLR_EL1 value in the cpu_context */ 326 #if (ERRATA_SPECULATIVE_AT) 327 write_ctx_reg(get_errata_speculative_at_ctx(ctx), 328 CTX_ERRATA_SPEC_AT_TCR_EL1, mmu_cfg_params[MMU_CFG_TCR]); 329 #else 330 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1, 331 mmu_cfg_params[MMU_CFG_TCR]); 332 #endif /* ERRATA_SPECULATIVE_AT */ 333 334 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1, 335 mmu_cfg_params[MMU_CFG_TTBR0]); 336 } 337 338 static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx) 339 { 340 u_register_t sctlr_el1_val; 341 342 /* Setup SCTLR_EL1 */ 343 #if (ERRATA_SPECULATIVE_AT) 344 sctlr_el1_val = read_ctx_reg(get_errata_speculative_at_ctx(ctx), 345 CTX_ERRATA_SPEC_AT_SCTLR_EL1); 346 #else 347 sctlr_el1_val = read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1); 348 #endif /* ERRATA_SPECULATIVE_AT */ 349 350 sctlr_el1_val |= 351 /*SCTLR_EL1_RES1 |*/ 352 /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */ 353 SCTLR_UCI_BIT | 354 /* RW regions at xlat regime EL1&0 are forced to be XN. */ 355 SCTLR_WXN_BIT | 356 /* Don't trap to EL1 execution of WFI or WFE at EL0. */ 357 SCTLR_NTWI_BIT | SCTLR_NTWE_BIT | 358 /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */ 359 SCTLR_UCT_BIT | 360 /* Don't trap to EL1 execution of DZ ZVA at EL0. */ 361 SCTLR_DZE_BIT | 362 /* Enable SP Alignment check for EL0 */ 363 SCTLR_SA0_BIT | 364 /* Don't change PSTATE.PAN on taking an exception to EL1 */ 365 SCTLR_SPAN_BIT | 366 /* Allow cacheable data and instr. accesses to normal memory. */ 367 SCTLR_C_BIT | SCTLR_I_BIT | 368 /* Enable MMU. */ 369 SCTLR_M_BIT; 370 371 sctlr_el1_val &= ~( 372 /* Explicit data accesses at EL0 are little-endian. */ 373 SCTLR_E0E_BIT | 374 /* 375 * Alignment fault checking disabled when at EL1 and EL0 as 376 * the UEFI spec permits unaligned accesses. 377 */ 378 SCTLR_A_BIT | 379 /* Accesses to DAIF from EL0 are trapped to EL1. */ 380 SCTLR_UMA_BIT 381 ); 382 383 /* Store the initialised SCTLR_EL1 value in the cpu_context */ 384 #if (ERRATA_SPECULATIVE_AT) 385 write_ctx_reg(get_errata_speculative_at_ctx(ctx), 386 CTX_ERRATA_SPEC_AT_SCTLR_EL1, sctlr_el1_val); 387 #else 388 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, sctlr_el1_val); 389 #endif /* ERRATA_SPECULATIVE_AT */ 390 } 391 392 static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp, 393 cpu_context_t *ctx) 394 { 395 396 spmc_el0_sp_setup_mmu(sp, ctx); 397 398 spmc_el0_sp_setup_sctlr_el1(ctx); 399 400 /* Setup other system registers. */ 401 402 /* Shim Exception Vector Base Address */ 403 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1, 404 SPM_SHIM_EXCEPTIONS_PTR); 405 #if NS_TIMER_SWITCH 406 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cntkctl_el1, 407 EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT); 408 #endif 409 410 /* 411 * FPEN: Allow the Secure Partition to access FP/SIMD registers. 412 * Note that SPM will not do any saving/restoring of these registers on 413 * behalf of the SP. This falls under the SP's responsibility. 414 * TTA: Enable access to trace registers. 415 * ZEN (v8.2): Trap SVE instructions and access to SVE registers. 416 */ 417 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1, 418 CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); 419 } 420 421 /* Setup context of an EL0 Secure Partition. */ 422 void spmc_el0_sp_setup(struct secure_partition_desc *sp, 423 int32_t boot_info_reg, 424 void *sp_manifest) 425 { 426 mmap_region_t sel1_exception_vectors = 427 MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START, 428 SPM_SHIM_EXCEPTIONS_SIZE, 429 MT_CODE | MT_SECURE | MT_PRIVILEGED); 430 cpu_context_t *ctx; 431 int node; 432 int offset = 0; 433 434 ctx = &sp->ec[SEL0_SP_EC_INDEX].cpu_ctx; 435 436 sp->xlat_ctx_handle->xlat_regime = EL1_EL0_REGIME; 437 438 /* This region contains the exception vectors used at S-EL1. */ 439 mmap_add_region_ctx(sp->xlat_ctx_handle, 440 &sel1_exception_vectors); 441 442 /* 443 * If the SP manifest specified the register to pass the address of the 444 * boot information, then map the memory region to pass boot 445 * information. 446 */ 447 if (boot_info_reg >= 0) { 448 mmap_region_t ffa_boot_info_region = MAP_REGION_FLAT( 449 (uintptr_t) ffa_boot_info_mem, 450 PAGE_SIZE, 451 MT_RO_DATA | MT_SECURE | MT_USER); 452 mmap_add_region_ctx(sp->xlat_ctx_handle, &ffa_boot_info_region); 453 } 454 455 /* 456 * Parse the manifest for any device regions that the SP wants to be 457 * mapped in its translation regime. 458 */ 459 node = fdt_subnode_offset_namelen(sp_manifest, offset, 460 "device-regions", 461 sizeof("device-regions") - 1); 462 if (node < 0) { 463 WARN("Not found device-region configuration for SP.\n"); 464 } else { 465 populate_sp_regions(sp, sp_manifest, node, 466 SP_MEM_REGION_DEVICE); 467 } 468 469 /* 470 * Parse the manifest for any memory regions that the SP wants to be 471 * mapped in its translation regime. 472 */ 473 node = fdt_subnode_offset_namelen(sp_manifest, offset, 474 "memory-regions", 475 sizeof("memory-regions") - 1); 476 if (node < 0) { 477 WARN("Not found memory-region configuration for SP.\n"); 478 } else { 479 populate_sp_regions(sp, sp_manifest, node, 480 SP_MEM_REGION_MEMORY); 481 } 482 483 spmc_el0_sp_setup_system_registers(sp, ctx); 484 485 } 486 #endif /* SPMC_AT_EL3_SEL0_SP */ 487 488 /* S-EL1 partition specific initialisation. */ 489 void spmc_el1_sp_setup(struct secure_partition_desc *sp, 490 entry_point_info_t *ep_info) 491 { 492 /* Sanity check input arguments. */ 493 assert(sp != NULL); 494 assert(ep_info != NULL); 495 496 /* Initialise the SPSR for S-EL1 SPs. */ 497 ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, 498 DISABLE_ALL_EXCEPTIONS); 499 500 /* 501 * TF-A Implementation defined behaviour to provide the linear 502 * core ID in the x4 register. 503 */ 504 ep_info->args.arg4 = (uintptr_t) plat_my_core_pos(); 505 506 /* 507 * Check whether setup is being performed for the primary or a secondary 508 * execution context. In the latter case, indicate to the SP that this 509 * is a warm boot. 510 * TODO: This check would need to be reworked if the same entry point is 511 * used for both primary and secondary initialisation. 512 */ 513 if (sp->secondary_ep != 0U) { 514 /* 515 * Sanity check that the secondary entry point is still what was 516 * originally set. 517 */ 518 assert(sp->secondary_ep == ep_info->pc); 519 ep_info->args.arg0 = FFA_WB_TYPE_S2RAM; 520 } 521 } 522 523 /* Common initialisation for all SPs. */ 524 void spmc_sp_common_setup(struct secure_partition_desc *sp, 525 entry_point_info_t *ep_info, 526 int32_t boot_info_reg) 527 { 528 uint16_t sp_id; 529 530 /* Assign FF-A Partition ID if not already assigned. */ 531 if (sp->sp_id == INV_SP_ID) { 532 sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX; 533 /* 534 * Ensure we don't clash with previously assigned partition 535 * IDs. 536 */ 537 while (!is_ffa_secure_id_valid(sp_id)) { 538 sp_id++; 539 540 if (sp_id == FFA_SWD_ID_LIMIT) { 541 ERROR("Unable to determine valid SP ID.\n"); 542 panic(); 543 } 544 } 545 sp->sp_id = sp_id; 546 } 547 548 /* Check if the SP wants to use the FF-A boot protocol. */ 549 if (boot_info_reg >= 0) { 550 /* 551 * Create a boot information descriptor and copy the partition 552 * manifest into the reserved memory region for consumption by 553 * the SP. 554 */ 555 spmc_create_boot_info(ep_info, sp); 556 557 /* 558 * We have consumed what we need from ep args so we can now 559 * zero them before we start populating with new information 560 * specifically for the SP. 561 */ 562 zeromem(&ep_info->args, sizeof(ep_info->args)); 563 564 /* 565 * Pass the address of the boot information in the 566 * boot_info_reg. 567 */ 568 switch (boot_info_reg) { 569 case 0: 570 ep_info->args.arg0 = (uintptr_t) ffa_boot_info_mem; 571 break; 572 case 1: 573 ep_info->args.arg1 = (uintptr_t) ffa_boot_info_mem; 574 break; 575 case 2: 576 ep_info->args.arg2 = (uintptr_t) ffa_boot_info_mem; 577 break; 578 case 3: 579 ep_info->args.arg3 = (uintptr_t) ffa_boot_info_mem; 580 break; 581 default: 582 ERROR("Invalid value for \"gp-register-num\" %d.\n", 583 boot_info_reg); 584 } 585 } else { 586 /* 587 * We don't need any of the information that was populated 588 * in ep_args so we can clear them. 589 */ 590 zeromem(&ep_info->args, sizeof(ep_info->args)); 591 } 592 } 593 594 /* 595 * Initialise the SP context now we have populated the common and EL specific 596 * entrypoint information. 597 */ 598 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp, 599 entry_point_info_t *ep_info) 600 { 601 cpu_context_t *cpu_ctx; 602 603 cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx); 604 print_entry_point_info(ep_info); 605 cm_setup_context(cpu_ctx, ep_info); 606 } 607