1 /*
2  * Copyright (c) 2022, 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  */
spmc_create_boot_info(entry_point_info_t * ep_info,struct secure_partition_desc * sp)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  */
get_ec_index(struct secure_partition_desc * sp)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. */
spmc_el0_sp_spsr_setup(entry_point_info_t * ep_info)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 
read_optional_string(void * manifest,int32_t offset,char * property,char * out,size_t len)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  ******************************************************************************/
populate_sp_regions(struct secure_partition_desc * sp,void * sp_manifest,int node,enum sp_memory_region_type type)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 
spmc_el0_sp_setup_mmu(struct secure_partition_desc * sp,cpu_context_t * ctx)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_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1,
323 		      mmu_cfg_params[MMU_CFG_MAIR]);
324 
325 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
326 		      mmu_cfg_params[MMU_CFG_TCR]);
327 
328 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1,
329 		      mmu_cfg_params[MMU_CFG_TTBR0]);
330 }
331 
spmc_el0_sp_setup_sctlr_el1(cpu_context_t * ctx)332 static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx)
333 {
334 	u_register_t sctlr_el1;
335 
336 	/* Setup SCTLR_EL1 */
337 	sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1);
338 
339 	sctlr_el1 |=
340 		/*SCTLR_EL1_RES1 |*/
341 		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
342 		SCTLR_UCI_BIT |
343 		/* RW regions at xlat regime EL1&0 are forced to be XN. */
344 		SCTLR_WXN_BIT |
345 		/* Don't trap to EL1 execution of WFI or WFE at EL0. */
346 		SCTLR_NTWI_BIT | SCTLR_NTWE_BIT |
347 		/* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
348 		SCTLR_UCT_BIT |
349 		/* Don't trap to EL1 execution of DZ ZVA at EL0. */
350 		SCTLR_DZE_BIT |
351 		/* Enable SP Alignment check for EL0 */
352 		SCTLR_SA0_BIT |
353 		/* Don't change PSTATE.PAN on taking an exception to EL1 */
354 		SCTLR_SPAN_BIT |
355 		/* Allow cacheable data and instr. accesses to normal memory. */
356 		SCTLR_C_BIT | SCTLR_I_BIT |
357 		/* Enable MMU. */
358 		SCTLR_M_BIT;
359 
360 	sctlr_el1 &= ~(
361 		/* Explicit data accesses at EL0 are little-endian. */
362 		SCTLR_E0E_BIT |
363 		/*
364 		 * Alignment fault checking disabled when at EL1 and EL0 as
365 		 * the UEFI spec permits unaligned accesses.
366 		 */
367 		SCTLR_A_BIT |
368 		/* Accesses to DAIF from EL0 are trapped to EL1. */
369 		SCTLR_UMA_BIT
370 	);
371 
372 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
373 }
374 
spmc_el0_sp_setup_system_registers(struct secure_partition_desc * sp,cpu_context_t * ctx)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_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1,
387 			SPM_SHIM_EXCEPTIONS_PTR);
388 #if NS_TIMER_SWITCH
389 	write_ctx_reg(get_el1_sysregs_ctx(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_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1,
401 			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
402 }
403 
404 /* Setup context of an EL0 Secure Partition.  */
spmc_el0_sp_setup(struct secure_partition_desc * sp,int32_t boot_info_reg,void * sp_manifest)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. */
spmc_el1_sp_setup(struct secure_partition_desc * sp,entry_point_info_t * ep_info)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. */
spmc_sp_common_setup(struct secure_partition_desc * sp,entry_point_info_t * ep_info,int32_t boot_info_reg)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 		 * Call platform specific hook to set ep_regs if FF-A boot
577 		 * protocol is not used
578 		 */
579 		plat_spmc_set_boot_info(ep_info);
580 	}
581 }
582 
583 #if !defined(TSP_SEC_MEM_SIZE) && defined(BL32_MEM_SIZE)
584 #define TSP_SEC_MEM_SIZE BL32_MEM_SIZE
585 #endif
586 
587 #pragma weak plat_spmc_set_boot_info
plat_spmc_set_boot_info(entry_point_info_t * ep_info)588 void plat_spmc_set_boot_info(entry_point_info_t *ep_info)
589 {
590 #ifdef TSP_SEC_MEM_SIZE
591 	ep_info->args.arg0 = TSP_SEC_MEM_SIZE;
592 #endif
593 }
594 
595 /*
596  * Initialise the SP context now we have populated the common and EL specific
597  * entrypoint information.
598  */
spmc_sp_common_ep_commit(struct secure_partition_desc * sp,entry_point_info_t * ep_info)599 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
600 			      entry_point_info_t *ep_info)
601 {
602 	cpu_context_t *cpu_ctx;
603 
604 	cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
605 	print_entry_point_info(ep_info);
606 	cm_setup_context(cpu_ctx, ep_info);
607 }
608