1 /* 2 * Copyright (c) 2022-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 <string.h> 10 11 #include <arch.h> 12 #include <arch_helpers.h> 13 #include <common/debug.h> 14 #include <common/fdt_wrappers.h> 15 16 #include <context.h> 17 #include <lib/el3_runtime/context_mgmt.h> 18 #if HOB_LIST 19 #include <lib/hob/hob.h> 20 #include <lib/hob/hob_guid.h> 21 #include <lib/hob/mmram.h> 22 #include <lib/hob/mpinfo.h> 23 #endif 24 #include <lib/utils.h> 25 #include <lib/xlat_tables/xlat_tables_v2.h> 26 #include <libfdt.h> 27 #include <plat/common/common_def.h> 28 #include <plat/common/platform.h> 29 #include <services/ffa_svc.h> 30 #include "spm_common.h" 31 #include "spm_shim_private.h" 32 #include "spmc.h" 33 #if TRANSFER_LIST 34 #include <transfer_list.h> 35 #include <drivers/measured_boot/event_log/event_handoff.h> 36 #endif 37 #include <tools_share/firmware_image_package.h> 38 39 #include <platform_def.h> 40 41 #define FFA_BOOT_INFO_SIZE (PAGE_SIZE * 2) 42 43 /* 44 * Statically allocate a page of memory for passing boot information to an SP. 45 */ 46 static uint8_t ffa_boot_info_mem[FFA_BOOT_INFO_SIZE] __aligned(PAGE_SIZE); 47 48 #if HOB_LIST 49 static void *tpm_evtlog_addr; 50 static size_t tpm_evtlog_size; 51 #endif 52 53 /* 54 * We need to choose one execution context from all those available for a S-EL0 55 * SP. This execution context will be used subsequently irrespective of which 56 * physical CPU the SP runs on. 57 */ 58 #define SEL0_SP_EC_INDEX 0 59 #define SP_MEM_READ 0x1 60 #define SP_MEM_WRITE 0x2 61 #define SP_MEM_EXECUTE 0x4 62 #define SP_MEM_NON_SECURE 0x8 63 #define SP_MEM_READ_ONLY SP_MEM_READ 64 #define SP_MEM_READ_WRITE (SP_MEM_READ | SP_MEM_WRITE) 65 66 /* Type of the memory region in SP's manifest. */ 67 enum sp_memory_region_type { 68 SP_MEM_REGION_DEVICE, 69 SP_MEM_REGION_MEMORY, 70 SP_MEM_REGION_NOT_SPECIFIED 71 }; 72 73 #if HOB_LIST 74 #if TRANSFER_LIST 75 static void get_tpm_event_log(void *secure_tl) 76 { 77 struct transfer_list_entry *te; 78 void *evlog; 79 80 if (secure_tl == NULL) { 81 tpm_evtlog_addr = NULL; 82 tpm_evtlog_size = 0; 83 return; 84 } 85 86 te = transfer_list_find((struct transfer_list_header *)secure_tl, 87 TL_TAG_TPM_EVLOG); 88 if (te == NULL) { 89 tpm_evtlog_addr = NULL; 90 tpm_evtlog_size = 0; 91 return; 92 } 93 94 evlog = transfer_list_entry_data(te); 95 assert(evlog != NULL); 96 97 tpm_evtlog_addr = evlog + EVENT_LOG_RESERVED_BYTES; 98 tpm_evtlog_size = te->data_size - EVENT_LOG_RESERVED_BYTES; 99 } 100 #else 101 static void get_tpm_event_log(void *secure_tl) 102 { 103 tpm_evtlog_addr = NULL; 104 tpm_evtlog_size = 0; 105 } 106 #endif 107 108 static int get_memory_region_info(void *sp_manifest, int mem_region_node, 109 const char *name, uint32_t granularity, 110 uint64_t *base_address, uint32_t *size) 111 { 112 char *property; 113 int node, ret; 114 115 if (name != NULL) { 116 node = fdt_subnode_offset_namelen(sp_manifest, mem_region_node, 117 name, strlen(name)); 118 if (node < 0) { 119 ERROR("Not found '%s' region in memory regions configuration for SP.\n", 120 name); 121 return -ENOENT; 122 } 123 } else { 124 node = mem_region_node; 125 } 126 127 property = "base-address"; 128 ret = fdt_read_uint64(sp_manifest, node, property, base_address); 129 if (ret < 0) { 130 ERROR("Not found property(%s) in memory region(%s).\n", 131 property, name); 132 return -ENOENT; 133 } 134 135 property = "pages-count"; 136 ret = fdt_read_uint32(sp_manifest, node, property, size); 137 if (ret < 0) { 138 ERROR("Not found property(%s) in memory region(%s).\n", 139 property, name); 140 return -ENOENT; 141 } 142 143 *size = ((*size) << (PAGE_SIZE_SHIFT + (granularity << 1))); 144 145 return 0; 146 } 147 148 static struct efi_hob_handoff_info_table *build_sp_boot_hob_list( 149 void *secure_tl, void *sp_manifest, 150 uintptr_t hob_table_start, size_t *hob_table_size) 151 { 152 struct efi_hob_handoff_info_table *hob_table; 153 uintptr_t base_address; 154 int mem_region_node; 155 int32_t node, ret; 156 const char *name; 157 uint32_t granularity, size; 158 uint32_t mem_region_num; 159 struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID; 160 struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID; 161 struct efi_guid tpm_evtlog_guid = MM_TPM_EVENT_LOG_GUID; 162 struct efi_mmram_descriptor *mmram_desc_data; 163 struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data; 164 165 if (sp_manifest == NULL || hob_table_size == NULL || *hob_table_size == 0) { 166 return NULL; 167 } 168 169 node = fdt_path_offset(sp_manifest, "/"); 170 if (node < 0) { 171 ERROR("Failed to get root in sp_manifest.\n"); 172 return NULL; 173 } 174 175 ret = fdt_read_uint32(sp_manifest, node, "xlat-granule", &granularity); 176 if (ret < 0) { 177 ERROR("Not found property(xlat-granule) in sp_manifest.\n"); 178 return NULL; 179 } 180 181 if (granularity > 0x02) { 182 ERROR("Invalid granularity value: 0x%x\n", granularity); 183 return NULL; 184 } 185 186 mem_region_node = fdt_subnode_offset_namelen(sp_manifest, 0, "memory-regions", 187 sizeof("memory-regions") - 1); 188 if (node < 0) { 189 ERROR("Not found memory-region configuration for SP.\n"); 190 return NULL; 191 } 192 193 INFO("Generating PHIT_HOB...\n"); 194 195 hob_table = create_hob_list(BL32_BASE, BL32_LIMIT, 196 hob_table_start, *hob_table_size); 197 if (hob_table == NULL) { 198 ERROR("Failed to create Hob Table.\n"); 199 return NULL; 200 } 201 202 /* 203 * Create fv hob. 204 */ 205 ret = get_memory_region_info(sp_manifest, mem_region_node, 206 "stmm_region", granularity, &base_address, &size); 207 if (ret < 0) { 208 return NULL; 209 } 210 211 if (base_address != BL32_BASE && 212 base_address + size > BL32_LIMIT) { 213 ERROR("Image is ouf of bound(0x%lx/0x%x), should be in (0x%llx/0x%llx)\n", 214 base_address, size, BL32_BASE, BL32_LIMIT - BL32_BASE); 215 return NULL; 216 } 217 218 ret = create_fv_hob(hob_table, base_address, size); 219 if (ret < 0) { 220 ERROR("Failed to create fv hob... ret:%d\n", ret); 221 return NULL; 222 } 223 224 INFO("Success to create FV hob(0x%lx/0x%x).\n", base_address, size); 225 226 /* 227 * Create Ns Buffer hob. 228 */ 229 ret = get_memory_region_info(sp_manifest, mem_region_node, 230 "ns_comm_buffer", granularity, &base_address, &size); 231 if (ret < 0) { 232 return NULL; 233 } 234 235 ret = create_guid_hob(hob_table, &ns_buf_guid, 236 sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data); 237 if (ret < 0) { 238 ERROR("Failed to create ns buffer hob\n"); 239 return NULL; 240 } 241 242 mmram_desc_data->physical_start = base_address; 243 mmram_desc_data->physical_size = size; 244 mmram_desc_data->cpu_start = base_address; 245 mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED; 246 247 /* 248 * Create mmram_resv hob. 249 */ 250 for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0; 251 node >= 0; 252 node = fdt_next_subnode(sp_manifest, node), mem_region_num++) { 253 ret = get_memory_region_info(sp_manifest, node, NULL, granularity, 254 &base_address, &size); 255 if (ret < 0) { 256 name = fdt_get_name(sp_manifest, node, NULL); 257 ERROR("Invalid memory region(%s) found!\n", name); 258 return NULL; 259 } 260 } 261 262 ret = create_guid_hob(hob_table, &mmram_resv_guid, 263 (sizeof(struct efi_mmram_hob_descriptor_block) + 264 (sizeof(struct efi_mmram_descriptor) * (mem_region_num))), 265 (void **) &mmram_hob_desc_data); 266 if (ret < 0) { 267 ERROR("Failed to create mmram_resv hob. ret: %d\n", ret); 268 return NULL; 269 } 270 271 mmram_hob_desc_data->number_of_mm_reserved_regions = mem_region_num; 272 273 for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0; 274 node >= 0; 275 node = fdt_next_subnode(sp_manifest, node), mem_region_num++) { 276 get_memory_region_info(sp_manifest, node, NULL, granularity, 277 &base_address, &size); 278 name = fdt_get_name(sp_manifest, node, NULL); 279 280 mmram_desc_data = &mmram_hob_desc_data->descriptor[mem_region_num]; 281 mmram_desc_data->physical_start = base_address; 282 mmram_desc_data->physical_size = size; 283 mmram_desc_data->cpu_start = base_address; 284 285 if (!strcmp(name, "heap")) { 286 mmram_desc_data->region_state = EFI_CACHEABLE; 287 } else { 288 mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED; 289 } 290 } 291 292 /* 293 * Add tpm mmram descriptor. 294 */ 295 get_tpm_event_log(secure_tl); 296 297 if (tpm_evtlog_addr != NULL && tpm_evtlog_size != 0) { 298 ret = create_guid_hob(hob_table, &tpm_evtlog_guid, 299 sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data); 300 if (ret < 0) { 301 ERROR("Failed to create tpm_event_log hob\n"); 302 return NULL; 303 } 304 305 mmram_desc_data->physical_start = (uintptr_t)tpm_evtlog_addr; 306 mmram_desc_data->physical_size = tpm_evtlog_size; 307 mmram_desc_data->cpu_start = (uintptr_t)tpm_evtlog_addr; 308 mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED; 309 } 310 311 *hob_table_size = hob_table->efi_free_memory_bottom - 312 (efi_physical_address_t) hob_table; 313 314 return hob_table; 315 } 316 #endif 317 318 /* 319 * This function creates a initialization descriptor in the memory reserved 320 * for passing boot information to an SP. It then copies the partition manifest 321 * into this region and ensures that its reference in the initialization 322 * descriptor is updated. 323 */ 324 static void spmc_create_boot_info(entry_point_info_t *ep_info, 325 struct secure_partition_desc *sp) 326 { 327 struct ffa_boot_info_header *boot_header; 328 struct ffa_boot_info_desc *boot_descriptor; 329 uintptr_t content_addr; 330 void *sp_manifest; 331 void *tl __maybe_unused; 332 #if TRANSFER_LIST && !RESET_TO_BL31 333 struct transfer_list_entry *te; 334 335 tl = (void *)((uintptr_t)ep_info->args.arg3); 336 te = transfer_list_find((struct transfer_list_header *)tl, 337 TL_TAG_DT_FFA_MANIFEST); 338 assert(te != NULL); 339 340 sp_manifest = (void *)transfer_list_entry_data(te); 341 #else 342 tl = NULL; 343 sp_manifest = (void *)ep_info->args.arg0; 344 #endif 345 346 /* 347 * Calculate the maximum size of the manifest that can be accommodated 348 * in the boot information memory region. 349 */ 350 size_t max_sz = sizeof(ffa_boot_info_mem) - 351 (sizeof(struct ffa_boot_info_header) + 352 sizeof(struct ffa_boot_info_desc)); 353 354 /* 355 * The current implementation only supports the FF-A v1.1 356 * implementation of the boot protocol, therefore check 357 * that a v1.0 SP has not requested use of the protocol. 358 */ 359 if (sp->ffa_version == MAKE_FFA_VERSION(1, 0)) { 360 ERROR("FF-A boot protocol not supported for v1.0 clients\n"); 361 return; 362 } 363 364 /* Zero the memory region before populating. */ 365 memset(ffa_boot_info_mem, 0, FFA_BOOT_INFO_SIZE); 366 367 /* 368 * Populate the ffa_boot_info_header at the start of the boot info 369 * region. 370 */ 371 boot_header = (struct ffa_boot_info_header *) ffa_boot_info_mem; 372 373 /* Position the ffa_boot_info_desc after the ffa_boot_info_header. */ 374 boot_header->offset_boot_info_desc = 375 sizeof(struct ffa_boot_info_header); 376 boot_descriptor = (struct ffa_boot_info_desc *) 377 (ffa_boot_info_mem + 378 boot_header->offset_boot_info_desc); 379 380 /* 381 * We must use the FF-A version corresponding to the version implemented 382 * by the SP. Currently this can only be v1.1. 383 */ 384 boot_header->version = sp->ffa_version; 385 386 /* Populate the boot information header. */ 387 boot_header->size_boot_info_desc = sizeof(struct ffa_boot_info_desc); 388 389 /* Set the signature "0xFFA". */ 390 boot_header->signature = FFA_INIT_DESC_SIGNATURE; 391 392 /* Set the count. Currently 1 since only the manifest is specified. */ 393 boot_header->count_boot_info_desc = 1; 394 395 boot_descriptor->flags = 396 FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) | 397 FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR); 398 399 content_addr = (uintptr_t) (ffa_boot_info_mem + 400 boot_header->offset_boot_info_desc + 401 boot_header->size_boot_info_desc); 402 403 #if HOB_LIST 404 /* Populate the boot information descriptor for the hob_list. */ 405 boot_descriptor->type = 406 FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) | 407 FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_HOB); 408 409 content_addr = (uintptr_t) build_sp_boot_hob_list( 410 tl, sp_manifest, content_addr, &max_sz); 411 if (content_addr == (uintptr_t) NULL) { 412 WARN("Unable to create phit hob properly."); 413 return; 414 } 415 416 boot_descriptor->size_boot_info = max_sz; 417 boot_descriptor->content = content_addr; 418 #else 419 /* 420 * Check if the manifest will fit into the boot info memory region else 421 * bail. 422 */ 423 if (ep_info->args.arg1 > max_sz) { 424 WARN("Unable to copy manifest into boot information. "); 425 WARN("Max sz = %lu bytes. Manifest sz = %lu bytes\n", 426 max_sz, ep_info->args.arg1); 427 return; 428 } 429 430 /* Populate the boot information descriptor for the manifest. */ 431 boot_descriptor->type = 432 FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) | 433 FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT); 434 435 /* 436 * Copy the manifest into boot info region after the boot information 437 * descriptor. 438 */ 439 boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1; 440 441 memcpy((void *) content_addr, sp_manifest, boot_descriptor->size_boot_info); 442 443 boot_descriptor->content = content_addr; 444 #endif 445 446 /* Calculate the size of the total boot info blob. */ 447 boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc + 448 boot_descriptor->size_boot_info + 449 (boot_header->count_boot_info_desc * 450 boot_header->size_boot_info_desc); 451 452 INFO("SP boot info @ 0x%lx, size: %u bytes.\n", 453 (uintptr_t) ffa_boot_info_mem, 454 boot_header->size_boot_info_blob); 455 INFO("SP content @ 0x%lx, size: %u bytes.\n", 456 boot_descriptor->content, 457 boot_descriptor->size_boot_info); 458 } 459 460 /* 461 * S-EL1 partitions can be assigned with multiple execution contexts, each 462 * pinned to the physical CPU. Each execution context index corresponds to the 463 * respective liner core position. 464 * S-EL0 partitions execute in a single execution context (index 0). 465 */ 466 unsigned int get_ec_index(struct secure_partition_desc *sp) 467 { 468 return (sp->runtime_el == S_EL0) ? 469 SEL0_SP_EC_INDEX : plat_my_core_pos(); 470 } 471 472 #if SPMC_AT_EL3_SEL0_SP 473 /* Setup spsr in entry point info for common context management code to use. */ 474 void spmc_el0_sp_spsr_setup(entry_point_info_t *ep_info) 475 { 476 /* Setup Secure Partition SPSR for S-EL0 SP. */ 477 ep_info->spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS); 478 } 479 480 static void read_optional_string(void *manifest, int32_t offset, 481 char *property, char *out, size_t len) 482 { 483 const fdt32_t *prop; 484 int lenp; 485 486 prop = fdt_getprop(manifest, offset, property, &lenp); 487 if (prop == NULL) { 488 out[0] = '\0'; 489 } else { 490 memcpy(out, prop, MIN(lenp, (int)len)); 491 out[MIN(lenp, (int)len) - 1] = '\0'; 492 } 493 } 494 495 /******************************************************************************* 496 * This function will parse the Secure Partition Manifest for fetching secure 497 * partition specific memory/device region details. It will find base address, 498 * size, memory attributes for each region and then add the respective region 499 * into secure parition's translation context. 500 ******************************************************************************/ 501 static void populate_sp_regions(struct secure_partition_desc *sp, 502 void *sp_manifest, int node, 503 enum sp_memory_region_type type) 504 { 505 uintptr_t base_address; 506 uint32_t mem_attr, mem_region, size; 507 struct mmap_region sp_mem_regions = {0}; 508 int32_t offset, ret; 509 char *compatibility[SP_MEM_REGION_NOT_SPECIFIED] = { 510 "arm,ffa-manifest-device-regions", 511 "arm,ffa-manifest-memory-regions" 512 }; 513 char description[10]; 514 char *property; 515 char *region[SP_MEM_REGION_NOT_SPECIFIED] = { 516 "device regions", 517 "memory regions" 518 }; 519 520 if (type >= SP_MEM_REGION_NOT_SPECIFIED) { 521 WARN("Invalid region type\n"); 522 return; 523 } 524 525 INFO("Mapping SP's %s\n", region[type]); 526 527 if (fdt_node_check_compatible(sp_manifest, node, 528 compatibility[type]) != 0) { 529 WARN("Incompatible region node in manifest\n"); 530 return; 531 } 532 533 for (offset = fdt_first_subnode(sp_manifest, node), mem_region = 0; 534 offset >= 0; 535 offset = fdt_next_subnode(sp_manifest, offset), mem_region++) { 536 read_optional_string(sp_manifest, offset, "description", 537 description, sizeof(description)); 538 539 INFO("Mapping: region: %d, %s\n", mem_region, description); 540 541 property = "base-address"; 542 ret = fdt_read_uint64(sp_manifest, offset, property, 543 &base_address); 544 if (ret < 0) { 545 WARN("Missing:%s for %s.\n", property, description); 546 continue; 547 } 548 549 property = "pages-count"; 550 ret = fdt_read_uint32(sp_manifest, offset, property, &size); 551 if (ret < 0) { 552 WARN("Missing: %s for %s.\n", property, description); 553 continue; 554 } 555 size *= PAGE_SIZE; 556 557 property = "attributes"; 558 ret = fdt_read_uint32(sp_manifest, offset, property, &mem_attr); 559 if (ret < 0) { 560 WARN("Missing: %s for %s.\n", property, description); 561 continue; 562 } 563 564 sp_mem_regions.attr = MT_USER; 565 if (type == SP_MEM_REGION_DEVICE) { 566 sp_mem_regions.attr |= MT_EXECUTE_NEVER; 567 } else { 568 sp_mem_regions.attr |= MT_MEMORY; 569 if ((mem_attr & SP_MEM_EXECUTE) == SP_MEM_EXECUTE) { 570 sp_mem_regions.attr &= ~MT_EXECUTE_NEVER; 571 } else { 572 sp_mem_regions.attr |= MT_EXECUTE_NEVER; 573 } 574 } 575 576 if ((mem_attr & SP_MEM_READ_WRITE) == SP_MEM_READ_WRITE) { 577 sp_mem_regions.attr |= MT_RW; 578 } 579 580 if ((mem_attr & SP_MEM_NON_SECURE) == SP_MEM_NON_SECURE) { 581 sp_mem_regions.attr |= MT_NS; 582 } else { 583 sp_mem_regions.attr |= MT_SECURE; 584 } 585 586 sp_mem_regions.base_pa = base_address; 587 sp_mem_regions.base_va = base_address; 588 sp_mem_regions.size = size; 589 590 INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx mem_attr: 0x%x, attr:0x%x\n", 591 sp_mem_regions.base_pa, 592 sp_mem_regions.base_va, 593 sp_mem_regions.size, 594 mem_attr, 595 sp_mem_regions.attr); 596 597 if (type == SP_MEM_REGION_DEVICE) { 598 sp_mem_regions.granularity = XLAT_BLOCK_SIZE(1); 599 } else { 600 sp_mem_regions.granularity = XLAT_BLOCK_SIZE(3); 601 } 602 mmap_add_region_ctx(sp->xlat_ctx_handle, &sp_mem_regions); 603 } 604 } 605 606 static void spmc_el0_sp_setup_mmu(struct secure_partition_desc *sp, 607 cpu_context_t *ctx) 608 { 609 xlat_ctx_t *xlat_ctx; 610 uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; 611 612 xlat_ctx = sp->xlat_ctx_handle; 613 init_xlat_tables_ctx(sp->xlat_ctx_handle); 614 setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table, 615 xlat_ctx->pa_max_address, xlat_ctx->va_max_address, 616 EL1_EL0_REGIME); 617 618 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1, 619 mmu_cfg_params[MMU_CFG_MAIR]); 620 621 write_ctx_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]); 622 623 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1, 624 mmu_cfg_params[MMU_CFG_TTBR0]); 625 } 626 627 static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx) 628 { 629 u_register_t sctlr_el1_val; 630 631 /* Setup SCTLR_EL1 */ 632 sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx); 633 634 sctlr_el1_val |= 635 /*SCTLR_EL1_RES1 |*/ 636 /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */ 637 SCTLR_UCI_BIT | 638 /* RW regions at xlat regime EL1&0 are forced to be XN. */ 639 SCTLR_WXN_BIT | 640 /* Don't trap to EL1 execution of WFI or WFE at EL0. */ 641 SCTLR_NTWI_BIT | SCTLR_NTWE_BIT | 642 /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */ 643 SCTLR_UCT_BIT | 644 /* Don't trap to EL1 execution of DZ ZVA at EL0. */ 645 SCTLR_DZE_BIT | 646 /* Enable SP Alignment check for EL0 */ 647 SCTLR_SA0_BIT | 648 /* Don't change PSTATE.PAN on taking an exception to EL1 */ 649 SCTLR_SPAN_BIT | 650 /* Allow cacheable data and instr. accesses to normal memory. */ 651 SCTLR_C_BIT | SCTLR_I_BIT | 652 /* Enable MMU. */ 653 SCTLR_M_BIT; 654 655 sctlr_el1_val &= ~( 656 /* Explicit data accesses at EL0 are little-endian. */ 657 SCTLR_E0E_BIT | 658 /* 659 * Alignment fault checking disabled when at EL1 and EL0 as 660 * the UEFI spec permits unaligned accesses. 661 */ 662 SCTLR_A_BIT | 663 /* Accesses to DAIF from EL0 are trapped to EL1. */ 664 SCTLR_UMA_BIT 665 ); 666 667 /* Store the initialised SCTLR_EL1 value in the cpu_context */ 668 write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val); 669 } 670 671 static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp, 672 cpu_context_t *ctx) 673 { 674 675 spmc_el0_sp_setup_mmu(sp, ctx); 676 677 spmc_el0_sp_setup_sctlr_el1(ctx); 678 679 /* Setup other system registers. */ 680 681 /* Shim Exception Vector Base Address */ 682 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1, 683 SPM_SHIM_EXCEPTIONS_PTR); 684 #if NS_TIMER_SWITCH 685 write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1, 686 EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT); 687 #endif 688 689 /* 690 * FPEN: Allow the Secure Partition to access FP/SIMD registers. 691 * Note that SPM will not do any saving/restoring of these registers on 692 * behalf of the SP. This falls under the SP's responsibility. 693 * TTA: Enable access to trace registers. 694 * ZEN (v8.2): Trap SVE instructions and access to SVE registers. 695 */ 696 write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1, 697 CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); 698 } 699 700 /* Setup context of an EL0 Secure Partition. */ 701 void spmc_el0_sp_setup(struct secure_partition_desc *sp, 702 int32_t boot_info_reg, 703 void *sp_manifest) 704 { 705 mmap_region_t sel1_exception_vectors = 706 MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START, 707 SPM_SHIM_EXCEPTIONS_SIZE, 708 MT_CODE | MT_SECURE | MT_PRIVILEGED); 709 cpu_context_t *ctx; 710 int node; 711 int offset = 0; 712 struct mmap_region sp_mem_regions __unused = {0}; 713 714 ctx = &sp->ec[SEL0_SP_EC_INDEX].cpu_ctx; 715 716 sp->xlat_ctx_handle->xlat_regime = EL1_EL0_REGIME; 717 718 /* This region contains the exception vectors used at S-EL1. */ 719 mmap_add_region_ctx(sp->xlat_ctx_handle, 720 &sel1_exception_vectors); 721 722 /* 723 * If the SP manifest specified the register to pass the address of the 724 * boot information, then map the memory region to pass boot 725 * information. 726 */ 727 if (boot_info_reg >= 0) { 728 mmap_region_t ffa_boot_info_region = MAP_REGION_FLAT( 729 (uintptr_t) ffa_boot_info_mem, 730 FFA_BOOT_INFO_SIZE, 731 MT_RO_DATA | MT_SECURE | MT_USER); 732 mmap_add_region_ctx(sp->xlat_ctx_handle, &ffa_boot_info_region); 733 } 734 735 /* 736 * Parse the manifest for any device regions that the SP wants to be 737 * mapped in its translation regime. 738 */ 739 node = fdt_subnode_offset_namelen(sp_manifest, offset, 740 "device-regions", 741 sizeof("device-regions") - 1); 742 if (node < 0) { 743 WARN("Not found device-region configuration for SP.\n"); 744 } else { 745 populate_sp_regions(sp, sp_manifest, node, 746 SP_MEM_REGION_DEVICE); 747 } 748 749 /* 750 * Parse the manifest for any memory regions that the SP wants to be 751 * mapped in its translation regime. 752 */ 753 node = fdt_subnode_offset_namelen(sp_manifest, offset, 754 "memory-regions", 755 sizeof("memory-regions") - 1); 756 if (node < 0) { 757 WARN("Not found memory-region configuration for SP.\n"); 758 } else { 759 populate_sp_regions(sp, sp_manifest, node, 760 SP_MEM_REGION_MEMORY); 761 } 762 763 #if HOB_LIST 764 /* 765 * Add tpm event log region with RO permission. 766 */ 767 if (tpm_evtlog_addr != NULL && tpm_evtlog_size != 0) { 768 INFO("Mapping SP's TPM event log\n"); 769 INFO("TPM event log addr(0x%lx), size(0x%lx)\n", 770 (uintptr_t)tpm_evtlog_addr, tpm_evtlog_size); 771 sp_mem_regions.base_pa = (uintptr_t) 772 ((unsigned long)tpm_evtlog_addr & ~(PAGE_SIZE_MASK)); 773 sp_mem_regions.base_va = sp_mem_regions.base_pa; 774 sp_mem_regions.size = (tpm_evtlog_size & ~(PAGE_SIZE_MASK)) + PAGE_SIZE; 775 sp_mem_regions.attr = MT_USER | MT_SECURE | MT_RO_DATA; 776 sp_mem_regions.granularity = XLAT_BLOCK_SIZE(3); 777 778 INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n", 779 sp_mem_regions.base_pa, 780 sp_mem_regions.base_va, 781 sp_mem_regions.size, 782 sp_mem_regions.attr); 783 784 mmap_add_region_ctx(sp->xlat_ctx_handle, &sp_mem_regions); 785 } 786 #endif 787 788 spmc_el0_sp_setup_system_registers(sp, ctx); 789 } 790 #endif /* SPMC_AT_EL3_SEL0_SP */ 791 792 /* S-EL1 partition specific initialisation. */ 793 void spmc_el1_sp_setup(struct secure_partition_desc *sp, 794 entry_point_info_t *ep_info) 795 { 796 /* Sanity check input arguments. */ 797 assert(sp != NULL); 798 assert(ep_info != NULL); 799 800 /* Initialise the SPSR for S-EL1 SPs. */ 801 ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, 802 DISABLE_ALL_EXCEPTIONS); 803 804 /* 805 * TF-A Implementation defined behaviour to provide the linear 806 * core ID in the x4 register. 807 */ 808 ep_info->args.arg4 = (uintptr_t) plat_my_core_pos(); 809 810 /* 811 * Check whether setup is being performed for the primary or a secondary 812 * execution context. In the latter case, indicate to the SP that this 813 * is a warm boot. 814 * TODO: This check would need to be reworked if the same entry point is 815 * used for both primary and secondary initialisation. 816 */ 817 if (sp->secondary_ep != 0U) { 818 /* 819 * Sanity check that the secondary entry point is still what was 820 * originally set. 821 */ 822 assert(sp->secondary_ep == ep_info->pc); 823 ep_info->args.arg0 = FFA_WB_TYPE_S2RAM; 824 } 825 } 826 827 /* Common initialisation for all SPs. */ 828 void spmc_sp_common_setup(struct secure_partition_desc *sp, 829 entry_point_info_t *ep_info, 830 int32_t boot_info_reg) 831 { 832 uint16_t sp_id; 833 834 /* Assign FF-A Partition ID if not already assigned. */ 835 if (sp->sp_id == INV_SP_ID) { 836 sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX; 837 /* 838 * Ensure we don't clash with previously assigned partition 839 * IDs. 840 */ 841 while (!is_ffa_secure_id_valid(sp_id)) { 842 sp_id++; 843 844 if (sp_id == FFA_SWD_ID_LIMIT) { 845 ERROR("Unable to determine valid SP ID.\n"); 846 panic(); 847 } 848 } 849 sp->sp_id = sp_id; 850 } 851 852 /* Check if the SP wants to use the FF-A boot protocol. */ 853 if (boot_info_reg >= 0) { 854 /* 855 * Create a boot information descriptor and copy the partition 856 * manifest into the reserved memory region for consumption by 857 * the SP. 858 */ 859 spmc_create_boot_info(ep_info, sp); 860 861 /* 862 * We have consumed what we need from ep args so we can now 863 * zero them before we start populating with new information 864 * specifically for the SP. 865 */ 866 zeromem(&ep_info->args, sizeof(ep_info->args)); 867 868 /* 869 * Pass the address of the boot information in the 870 * boot_info_reg. 871 */ 872 switch (boot_info_reg) { 873 case 0: 874 ep_info->args.arg0 = (uintptr_t) ffa_boot_info_mem; 875 break; 876 case 1: 877 ep_info->args.arg1 = (uintptr_t) ffa_boot_info_mem; 878 break; 879 case 2: 880 ep_info->args.arg2 = (uintptr_t) ffa_boot_info_mem; 881 break; 882 case 3: 883 ep_info->args.arg3 = (uintptr_t) ffa_boot_info_mem; 884 break; 885 default: 886 ERROR("Invalid value for \"gp-register-num\" %d.\n", 887 boot_info_reg); 888 } 889 } else { 890 /* 891 * We don't need any of the information that was populated 892 * in ep_args so we can clear them. 893 */ 894 zeromem(&ep_info->args, sizeof(ep_info->args)); 895 } 896 } 897 898 /* 899 * Initialise the SP context now we have populated the common and EL specific 900 * entrypoint information. 901 */ 902 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp, 903 entry_point_info_t *ep_info) 904 { 905 cpu_context_t *cpu_ctx; 906 907 cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx); 908 print_entry_point_info(ep_info); 909 cm_setup_context(cpu_ctx, ep_info); 910 } 911