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 write_ctx_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]); 326 327 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1, 328 mmu_cfg_params[MMU_CFG_TTBR0]); 329 } 330 331 static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx) 332 { 333 u_register_t sctlr_el1_val; 334 335 /* Setup SCTLR_EL1 */ 336 sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx); 337 338 sctlr_el1_val |= 339 /*SCTLR_EL1_RES1 |*/ 340 /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */ 341 SCTLR_UCI_BIT | 342 /* RW regions at xlat regime EL1&0 are forced to be XN. */ 343 SCTLR_WXN_BIT | 344 /* Don't trap to EL1 execution of WFI or WFE at EL0. */ 345 SCTLR_NTWI_BIT | SCTLR_NTWE_BIT | 346 /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */ 347 SCTLR_UCT_BIT | 348 /* Don't trap to EL1 execution of DZ ZVA at EL0. */ 349 SCTLR_DZE_BIT | 350 /* Enable SP Alignment check for EL0 */ 351 SCTLR_SA0_BIT | 352 /* Don't change PSTATE.PAN on taking an exception to EL1 */ 353 SCTLR_SPAN_BIT | 354 /* Allow cacheable data and instr. accesses to normal memory. */ 355 SCTLR_C_BIT | SCTLR_I_BIT | 356 /* Enable MMU. */ 357 SCTLR_M_BIT; 358 359 sctlr_el1_val &= ~( 360 /* Explicit data accesses at EL0 are little-endian. */ 361 SCTLR_E0E_BIT | 362 /* 363 * Alignment fault checking disabled when at EL1 and EL0 as 364 * the UEFI spec permits unaligned accesses. 365 */ 366 SCTLR_A_BIT | 367 /* Accesses to DAIF from EL0 are trapped to EL1. */ 368 SCTLR_UMA_BIT 369 ); 370 371 /* Store the initialised SCTLR_EL1 value in the cpu_context */ 372 write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val); 373 } 374 375 static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp, 376 cpu_context_t *ctx) 377 { 378 379 spmc_el0_sp_setup_mmu(sp, ctx); 380 381 spmc_el0_sp_setup_sctlr_el1(ctx); 382 383 /* Setup other system registers. */ 384 385 /* Shim Exception Vector Base Address */ 386 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1, 387 SPM_SHIM_EXCEPTIONS_PTR); 388 #if NS_TIMER_SWITCH 389 write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1, 390 EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT); 391 #endif 392 393 /* 394 * FPEN: Allow the Secure Partition to access FP/SIMD registers. 395 * Note that SPM will not do any saving/restoring of these registers on 396 * behalf of the SP. This falls under the SP's responsibility. 397 * TTA: Enable access to trace registers. 398 * ZEN (v8.2): Trap SVE instructions and access to SVE registers. 399 */ 400 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1, 401 CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); 402 } 403 404 /* Setup context of an EL0 Secure Partition. */ 405 void spmc_el0_sp_setup(struct secure_partition_desc *sp, 406 int32_t boot_info_reg, 407 void *sp_manifest) 408 { 409 mmap_region_t sel1_exception_vectors = 410 MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START, 411 SPM_SHIM_EXCEPTIONS_SIZE, 412 MT_CODE | MT_SECURE | MT_PRIVILEGED); 413 cpu_context_t *ctx; 414 int node; 415 int offset = 0; 416 417 ctx = &sp->ec[SEL0_SP_EC_INDEX].cpu_ctx; 418 419 sp->xlat_ctx_handle->xlat_regime = EL1_EL0_REGIME; 420 421 /* This region contains the exception vectors used at S-EL1. */ 422 mmap_add_region_ctx(sp->xlat_ctx_handle, 423 &sel1_exception_vectors); 424 425 /* 426 * If the SP manifest specified the register to pass the address of the 427 * boot information, then map the memory region to pass boot 428 * information. 429 */ 430 if (boot_info_reg >= 0) { 431 mmap_region_t ffa_boot_info_region = MAP_REGION_FLAT( 432 (uintptr_t) ffa_boot_info_mem, 433 PAGE_SIZE, 434 MT_RO_DATA | MT_SECURE | MT_USER); 435 mmap_add_region_ctx(sp->xlat_ctx_handle, &ffa_boot_info_region); 436 } 437 438 /* 439 * Parse the manifest for any device regions that the SP wants to be 440 * mapped in its translation regime. 441 */ 442 node = fdt_subnode_offset_namelen(sp_manifest, offset, 443 "device-regions", 444 sizeof("device-regions") - 1); 445 if (node < 0) { 446 WARN("Not found device-region configuration for SP.\n"); 447 } else { 448 populate_sp_regions(sp, sp_manifest, node, 449 SP_MEM_REGION_DEVICE); 450 } 451 452 /* 453 * Parse the manifest for any memory regions that the SP wants to be 454 * mapped in its translation regime. 455 */ 456 node = fdt_subnode_offset_namelen(sp_manifest, offset, 457 "memory-regions", 458 sizeof("memory-regions") - 1); 459 if (node < 0) { 460 WARN("Not found memory-region configuration for SP.\n"); 461 } else { 462 populate_sp_regions(sp, sp_manifest, node, 463 SP_MEM_REGION_MEMORY); 464 } 465 466 spmc_el0_sp_setup_system_registers(sp, ctx); 467 468 } 469 #endif /* SPMC_AT_EL3_SEL0_SP */ 470 471 /* S-EL1 partition specific initialisation. */ 472 void spmc_el1_sp_setup(struct secure_partition_desc *sp, 473 entry_point_info_t *ep_info) 474 { 475 /* Sanity check input arguments. */ 476 assert(sp != NULL); 477 assert(ep_info != NULL); 478 479 /* Initialise the SPSR for S-EL1 SPs. */ 480 ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, 481 DISABLE_ALL_EXCEPTIONS); 482 483 /* 484 * TF-A Implementation defined behaviour to provide the linear 485 * core ID in the x4 register. 486 */ 487 ep_info->args.arg4 = (uintptr_t) plat_my_core_pos(); 488 489 /* 490 * Check whether setup is being performed for the primary or a secondary 491 * execution context. In the latter case, indicate to the SP that this 492 * is a warm boot. 493 * TODO: This check would need to be reworked if the same entry point is 494 * used for both primary and secondary initialisation. 495 */ 496 if (sp->secondary_ep != 0U) { 497 /* 498 * Sanity check that the secondary entry point is still what was 499 * originally set. 500 */ 501 assert(sp->secondary_ep == ep_info->pc); 502 ep_info->args.arg0 = FFA_WB_TYPE_S2RAM; 503 } 504 } 505 506 /* Common initialisation for all SPs. */ 507 void spmc_sp_common_setup(struct secure_partition_desc *sp, 508 entry_point_info_t *ep_info, 509 int32_t boot_info_reg) 510 { 511 uint16_t sp_id; 512 513 /* Assign FF-A Partition ID if not already assigned. */ 514 if (sp->sp_id == INV_SP_ID) { 515 sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX; 516 /* 517 * Ensure we don't clash with previously assigned partition 518 * IDs. 519 */ 520 while (!is_ffa_secure_id_valid(sp_id)) { 521 sp_id++; 522 523 if (sp_id == FFA_SWD_ID_LIMIT) { 524 ERROR("Unable to determine valid SP ID.\n"); 525 panic(); 526 } 527 } 528 sp->sp_id = sp_id; 529 } 530 531 /* Check if the SP wants to use the FF-A boot protocol. */ 532 if (boot_info_reg >= 0) { 533 /* 534 * Create a boot information descriptor and copy the partition 535 * manifest into the reserved memory region for consumption by 536 * the SP. 537 */ 538 spmc_create_boot_info(ep_info, sp); 539 540 /* 541 * We have consumed what we need from ep args so we can now 542 * zero them before we start populating with new information 543 * specifically for the SP. 544 */ 545 zeromem(&ep_info->args, sizeof(ep_info->args)); 546 547 /* 548 * Pass the address of the boot information in the 549 * boot_info_reg. 550 */ 551 switch (boot_info_reg) { 552 case 0: 553 ep_info->args.arg0 = (uintptr_t) ffa_boot_info_mem; 554 break; 555 case 1: 556 ep_info->args.arg1 = (uintptr_t) ffa_boot_info_mem; 557 break; 558 case 2: 559 ep_info->args.arg2 = (uintptr_t) ffa_boot_info_mem; 560 break; 561 case 3: 562 ep_info->args.arg3 = (uintptr_t) ffa_boot_info_mem; 563 break; 564 default: 565 ERROR("Invalid value for \"gp-register-num\" %d.\n", 566 boot_info_reg); 567 } 568 } else { 569 /* 570 * We don't need any of the information that was populated 571 * in ep_args so we can clear them. 572 */ 573 zeromem(&ep_info->args, sizeof(ep_info->args)); 574 } 575 } 576 577 /* 578 * Initialise the SP context now we have populated the common and EL specific 579 * entrypoint information. 580 */ 581 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp, 582 entry_point_info_t *ep_info) 583 { 584 cpu_context_t *cpu_ctx; 585 586 cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx); 587 print_entry_point_info(ep_info); 588 cm_setup_context(cpu_ctx, ep_info); 589 } 590