xref: /rk3399_ARM-atf/services/std_svc/spm/el3_spmc/spmc_setup.c (revision ac44b9c7726e12d798a4cc5310da3710099a19b1)
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 <tpm_event_log.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 	write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1,
685 		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
686 
687 	/*
688 	 * FPEN: Allow the Secure Partition to access FP/SIMD registers.
689 	 * Note that SPM will not do any saving/restoring of these registers on
690 	 * behalf of the SP. This falls under the SP's responsibility.
691 	 * TTA: Enable access to trace registers.
692 	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
693 	 */
694 	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1,
695 			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
696 }
697 
698 /* Setup context of an EL0 Secure Partition.  */
699 void spmc_el0_sp_setup(struct secure_partition_desc *sp,
700 		       int32_t boot_info_reg,
701 		       void *sp_manifest)
702 {
703 	mmap_region_t sel1_exception_vectors =
704 		MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START,
705 				SPM_SHIM_EXCEPTIONS_SIZE,
706 				MT_CODE | MT_SECURE | MT_PRIVILEGED);
707 	cpu_context_t *ctx;
708 	int node;
709 	int offset = 0;
710 	struct mmap_region sp_mem_regions __unused = {0};
711 
712 	ctx = &sp->ec[SEL0_SP_EC_INDEX].cpu_ctx;
713 
714 	sp->xlat_ctx_handle->xlat_regime = EL1_EL0_REGIME;
715 
716 	/* This region contains the exception vectors used at S-EL1. */
717 	mmap_add_region_ctx(sp->xlat_ctx_handle,
718 			    &sel1_exception_vectors);
719 
720 	/*
721 	 * If the SP manifest specified the register to pass the address of the
722 	 * boot information, then map the memory region to pass boot
723 	 * information.
724 	 */
725 	if (boot_info_reg >= 0) {
726 		mmap_region_t ffa_boot_info_region = MAP_REGION_FLAT(
727 			(uintptr_t) ffa_boot_info_mem,
728 			FFA_BOOT_INFO_SIZE,
729 			MT_RO_DATA | MT_SECURE | MT_USER);
730 		mmap_add_region_ctx(sp->xlat_ctx_handle, &ffa_boot_info_region);
731 	}
732 
733 	/*
734 	 * Parse the manifest for any device regions that the SP wants to be
735 	 * mapped in its translation regime.
736 	 */
737 	node = fdt_subnode_offset_namelen(sp_manifest, offset,
738 					  "device-regions",
739 					  sizeof("device-regions") - 1);
740 	if (node < 0) {
741 		WARN("Not found device-region configuration for SP.\n");
742 	} else {
743 		populate_sp_regions(sp, sp_manifest, node,
744 				    SP_MEM_REGION_DEVICE);
745 	}
746 
747 	/*
748 	 * Parse the manifest for any memory regions that the SP wants to be
749 	 * mapped in its translation regime.
750 	 */
751 	node = fdt_subnode_offset_namelen(sp_manifest, offset,
752 					  "memory-regions",
753 					  sizeof("memory-regions") - 1);
754 	if (node < 0) {
755 		WARN("Not found memory-region configuration for SP.\n");
756 	} else {
757 		populate_sp_regions(sp, sp_manifest, node,
758 				    SP_MEM_REGION_MEMORY);
759 	}
760 
761 #if HOB_LIST
762 	/*
763 	 * Add tpm event log region with RO permission.
764 	 */
765 	if (tpm_evtlog_addr != NULL && tpm_evtlog_size != 0) {
766 		INFO("Mapping SP's TPM event log\n");
767 		INFO("TPM event log addr(0x%lx), size(0x%lx)\n",
768 				(uintptr_t)tpm_evtlog_addr, tpm_evtlog_size);
769 		sp_mem_regions.base_pa = (uintptr_t)
770 			((unsigned long)tpm_evtlog_addr & ~(PAGE_SIZE_MASK));
771 		sp_mem_regions.base_va = sp_mem_regions.base_pa;
772 		sp_mem_regions.size = (tpm_evtlog_size & ~(PAGE_SIZE_MASK)) + PAGE_SIZE;
773 		sp_mem_regions.attr = MT_USER | MT_SECURE | MT_RO_DATA;
774 		sp_mem_regions.granularity = XLAT_BLOCK_SIZE(3);
775 
776 		INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n",
777 		     sp_mem_regions.base_pa,
778 		     sp_mem_regions.base_va,
779 		     sp_mem_regions.size,
780 		     sp_mem_regions.attr);
781 
782 		mmap_add_region_ctx(sp->xlat_ctx_handle, &sp_mem_regions);
783 	}
784 #endif
785 
786 	spmc_el0_sp_setup_system_registers(sp, ctx);
787 }
788 #endif /* SPMC_AT_EL3_SEL0_SP */
789 
790 /* S-EL1 partition specific initialisation. */
791 void spmc_el1_sp_setup(struct secure_partition_desc *sp,
792 		       entry_point_info_t *ep_info)
793 {
794 	/* Sanity check input arguments. */
795 	assert(sp != NULL);
796 	assert(ep_info != NULL);
797 
798 	/* Initialise the SPSR for S-EL1 SPs. */
799 	ep_info->spsr =	SPSR_64(MODE_EL1, MODE_SP_ELX,
800 				DISABLE_ALL_EXCEPTIONS);
801 
802 	/*
803 	 * TF-A Implementation defined behaviour to provide the linear
804 	 * core ID in the x4 register.
805 	 */
806 	ep_info->args.arg4 = (uintptr_t) plat_my_core_pos();
807 
808 	/*
809 	 * Check whether setup is being performed for the primary or a secondary
810 	 * execution context. In the latter case, indicate to the SP that this
811 	 * is a warm boot.
812 	 * TODO: This check would need to be reworked if the same entry point is
813 	 * used for both primary and secondary initialisation.
814 	 */
815 	if (sp->secondary_ep != 0U) {
816 		/*
817 		 * Sanity check that the secondary entry point is still what was
818 		 * originally set.
819 		 */
820 		assert(sp->secondary_ep == ep_info->pc);
821 		ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
822 	}
823 }
824 
825 /* Common initialisation for all SPs. */
826 void spmc_sp_common_setup(struct secure_partition_desc *sp,
827 			  entry_point_info_t *ep_info,
828 			  int32_t boot_info_reg)
829 {
830 	uint16_t sp_id;
831 
832 	/* Assign FF-A Partition ID if not already assigned. */
833 	if (sp->sp_id == INV_SP_ID) {
834 		sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
835 		/*
836 		 * Ensure we don't clash with previously assigned partition
837 		 * IDs.
838 		 */
839 		while (!is_ffa_secure_id_valid(sp_id)) {
840 			sp_id++;
841 
842 			if (sp_id == FFA_SWD_ID_LIMIT) {
843 				ERROR("Unable to determine valid SP ID.\n");
844 				panic();
845 			}
846 		}
847 		sp->sp_id = sp_id;
848 	}
849 
850 	/* Check if the SP wants to use the FF-A boot protocol. */
851 	if (boot_info_reg >= 0) {
852 		/*
853 		 * Create a boot information descriptor and copy the partition
854 		 * manifest into the reserved memory region for consumption by
855 		 * the SP.
856 		 */
857 		spmc_create_boot_info(ep_info, sp);
858 
859 		/*
860 		 * We have consumed what we need from ep args so we can now
861 		 * zero them before we start populating with new information
862 		 * specifically for the SP.
863 		 */
864 		zeromem(&ep_info->args, sizeof(ep_info->args));
865 
866 		/*
867 		 * Pass the address of the boot information in the
868 		 * boot_info_reg.
869 		 */
870 		switch (boot_info_reg) {
871 		case 0:
872 			ep_info->args.arg0 = (uintptr_t) ffa_boot_info_mem;
873 			break;
874 		case 1:
875 			ep_info->args.arg1 = (uintptr_t) ffa_boot_info_mem;
876 			break;
877 		case 2:
878 			ep_info->args.arg2 = (uintptr_t) ffa_boot_info_mem;
879 			break;
880 		case 3:
881 			ep_info->args.arg3 = (uintptr_t) ffa_boot_info_mem;
882 			break;
883 		default:
884 			ERROR("Invalid value for \"gp-register-num\" %d.\n",
885 			      boot_info_reg);
886 		}
887 	} else {
888 		/*
889 		 * We don't need any of the information that was populated
890 		 * in ep_args so we can clear them.
891 		 */
892 		zeromem(&ep_info->args, sizeof(ep_info->args));
893 	}
894 }
895 
896 /*
897  * Initialise the SP context now we have populated the common and EL specific
898  * entrypoint information.
899  */
900 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
901 			      entry_point_info_t *ep_info)
902 {
903 	cpu_context_t *cpu_ctx;
904 
905 	cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
906 	print_entry_point_info(ep_info);
907 	cm_setup_context(cpu_ctx, ep_info);
908 }
909