xref: /arm-trusted-firmware/plat/qemu/common/qemu_bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <string.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <libfdt.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <platform_def.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #include <arch_helpers.h>
15*91f16700Schasinglulu #include <common/bl_common.h>
16*91f16700Schasinglulu #include <common/debug.h>
17*91f16700Schasinglulu #include <common/desc_image_load.h>
18*91f16700Schasinglulu #include <common/fdt_fixup.h>
19*91f16700Schasinglulu #include <common/fdt_wrappers.h>
20*91f16700Schasinglulu #include <lib/optee_utils.h>
21*91f16700Schasinglulu #if TRANSFER_LIST
22*91f16700Schasinglulu #include <lib/transfer_list.h>
23*91f16700Schasinglulu #endif
24*91f16700Schasinglulu #include <lib/utils.h>
25*91f16700Schasinglulu #include <plat/common/platform.h>
26*91f16700Schasinglulu 
27*91f16700Schasinglulu #include "qemu_private.h"
28*91f16700Schasinglulu 
29*91f16700Schasinglulu #define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
30*91f16700Schasinglulu 					bl2_tzram_layout.total_base,	\
31*91f16700Schasinglulu 					bl2_tzram_layout.total_size,	\
32*91f16700Schasinglulu 					MT_MEMORY | MT_RW | MT_SECURE)
33*91f16700Schasinglulu 
34*91f16700Schasinglulu #define MAP_BL2_RO		MAP_REGION_FLAT(			\
35*91f16700Schasinglulu 					BL_CODE_BASE,			\
36*91f16700Schasinglulu 					BL_CODE_END - BL_CODE_BASE,	\
37*91f16700Schasinglulu 					MT_CODE | MT_SECURE),		\
38*91f16700Schasinglulu 				MAP_REGION_FLAT(			\
39*91f16700Schasinglulu 					BL_RO_DATA_BASE,		\
40*91f16700Schasinglulu 					BL_RO_DATA_END			\
41*91f16700Schasinglulu 						- BL_RO_DATA_BASE,	\
42*91f16700Schasinglulu 					MT_RO_DATA | MT_SECURE)
43*91f16700Schasinglulu 
44*91f16700Schasinglulu #if USE_COHERENT_MEM
45*91f16700Schasinglulu #define MAP_BL_COHERENT_RAM	MAP_REGION_FLAT(			\
46*91f16700Schasinglulu 					BL_COHERENT_RAM_BASE,		\
47*91f16700Schasinglulu 					BL_COHERENT_RAM_END		\
48*91f16700Schasinglulu 						- BL_COHERENT_RAM_BASE,	\
49*91f16700Schasinglulu 					MT_DEVICE | MT_RW | MT_SECURE)
50*91f16700Schasinglulu #endif
51*91f16700Schasinglulu 
52*91f16700Schasinglulu /* Data structure which holds the extents of the trusted SRAM for BL2 */
53*91f16700Schasinglulu static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
54*91f16700Schasinglulu #if TRANSFER_LIST
55*91f16700Schasinglulu static struct transfer_list_header *bl2_tl;
56*91f16700Schasinglulu #endif
57*91f16700Schasinglulu 
58*91f16700Schasinglulu void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
59*91f16700Schasinglulu 			       u_register_t arg2, u_register_t arg3)
60*91f16700Schasinglulu {
61*91f16700Schasinglulu 	meminfo_t *mem_layout = (void *)arg1;
62*91f16700Schasinglulu 
63*91f16700Schasinglulu 	/* Initialize the console to provide early debug support */
64*91f16700Schasinglulu 	qemu_console_init();
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	/* Setup the BL2 memory layout */
67*91f16700Schasinglulu 	bl2_tzram_layout = *mem_layout;
68*91f16700Schasinglulu 
69*91f16700Schasinglulu 	plat_qemu_io_setup();
70*91f16700Schasinglulu }
71*91f16700Schasinglulu 
72*91f16700Schasinglulu static void security_setup(void)
73*91f16700Schasinglulu {
74*91f16700Schasinglulu 	/*
75*91f16700Schasinglulu 	 * This is where a TrustZone address space controller and other
76*91f16700Schasinglulu 	 * security related peripherals, would be configured.
77*91f16700Schasinglulu 	 */
78*91f16700Schasinglulu }
79*91f16700Schasinglulu 
80*91f16700Schasinglulu static void update_dt(void)
81*91f16700Schasinglulu {
82*91f16700Schasinglulu #if TRANSFER_LIST
83*91f16700Schasinglulu 	struct transfer_list_entry *te;
84*91f16700Schasinglulu #endif
85*91f16700Schasinglulu 	int ret;
86*91f16700Schasinglulu 	void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
87*91f16700Schasinglulu 
88*91f16700Schasinglulu 	ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
89*91f16700Schasinglulu 	if (ret < 0) {
90*91f16700Schasinglulu 		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
91*91f16700Schasinglulu 		return;
92*91f16700Schasinglulu 	}
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 	if (dt_add_psci_node(fdt)) {
95*91f16700Schasinglulu 		ERROR("Failed to add PSCI Device Tree node\n");
96*91f16700Schasinglulu 		return;
97*91f16700Schasinglulu 	}
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 	if (dt_add_psci_cpu_enable_methods(fdt)) {
100*91f16700Schasinglulu 		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
101*91f16700Schasinglulu 		return;
102*91f16700Schasinglulu 	}
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	ret = fdt_pack(fdt);
105*91f16700Schasinglulu 	if (ret < 0)
106*91f16700Schasinglulu 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
107*91f16700Schasinglulu 
108*91f16700Schasinglulu #if TRANSFER_LIST
109*91f16700Schasinglulu 	// create a TE
110*91f16700Schasinglulu 	te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
111*91f16700Schasinglulu 	if (!te) {
112*91f16700Schasinglulu 		ERROR("Failed to add FDT entry to Transfer List\n");
113*91f16700Schasinglulu 		return;
114*91f16700Schasinglulu 	}
115*91f16700Schasinglulu #endif
116*91f16700Schasinglulu }
117*91f16700Schasinglulu 
118*91f16700Schasinglulu void bl2_platform_setup(void)
119*91f16700Schasinglulu {
120*91f16700Schasinglulu #if TRANSFER_LIST
121*91f16700Schasinglulu 	bl2_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
122*91f16700Schasinglulu 				    FW_HANDOFF_SIZE);
123*91f16700Schasinglulu 	if (!bl2_tl) {
124*91f16700Schasinglulu 		ERROR("Failed to initialize Transfer List at 0x%lx\n",
125*91f16700Schasinglulu 		      (unsigned long)FW_HANDOFF_BASE);
126*91f16700Schasinglulu 	}
127*91f16700Schasinglulu #endif
128*91f16700Schasinglulu 	security_setup();
129*91f16700Schasinglulu 	update_dt();
130*91f16700Schasinglulu 
131*91f16700Schasinglulu 	/* TODO Initialize timer */
132*91f16700Schasinglulu }
133*91f16700Schasinglulu 
134*91f16700Schasinglulu void qemu_bl2_sync_transfer_list(void)
135*91f16700Schasinglulu {
136*91f16700Schasinglulu #if TRANSFER_LIST
137*91f16700Schasinglulu 	transfer_list_update_checksum(bl2_tl);
138*91f16700Schasinglulu #endif
139*91f16700Schasinglulu }
140*91f16700Schasinglulu 
141*91f16700Schasinglulu void bl2_plat_arch_setup(void)
142*91f16700Schasinglulu {
143*91f16700Schasinglulu 	const mmap_region_t bl_regions[] = {
144*91f16700Schasinglulu 		MAP_BL2_TOTAL,
145*91f16700Schasinglulu 		MAP_BL2_RO,
146*91f16700Schasinglulu #if USE_COHERENT_MEM
147*91f16700Schasinglulu 		MAP_BL_COHERENT_RAM,
148*91f16700Schasinglulu #endif
149*91f16700Schasinglulu 		{0}
150*91f16700Schasinglulu 	};
151*91f16700Schasinglulu 
152*91f16700Schasinglulu 	setup_page_tables(bl_regions, plat_qemu_get_mmap());
153*91f16700Schasinglulu 
154*91f16700Schasinglulu #ifdef __aarch64__
155*91f16700Schasinglulu 	enable_mmu_el1(0);
156*91f16700Schasinglulu #else
157*91f16700Schasinglulu 	enable_mmu_svc_mon(0);
158*91f16700Schasinglulu #endif
159*91f16700Schasinglulu }
160*91f16700Schasinglulu 
161*91f16700Schasinglulu /*******************************************************************************
162*91f16700Schasinglulu  * Gets SPSR for BL32 entry
163*91f16700Schasinglulu  ******************************************************************************/
164*91f16700Schasinglulu static uint32_t qemu_get_spsr_for_bl32_entry(void)
165*91f16700Schasinglulu {
166*91f16700Schasinglulu #ifdef __aarch64__
167*91f16700Schasinglulu 	/*
168*91f16700Schasinglulu 	 * The Secure Payload Dispatcher service is responsible for
169*91f16700Schasinglulu 	 * setting the SPSR prior to entry into the BL3-2 image.
170*91f16700Schasinglulu 	 */
171*91f16700Schasinglulu 	return 0;
172*91f16700Schasinglulu #else
173*91f16700Schasinglulu 	return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE,
174*91f16700Schasinglulu 			   DISABLE_ALL_EXCEPTIONS);
175*91f16700Schasinglulu #endif
176*91f16700Schasinglulu }
177*91f16700Schasinglulu 
178*91f16700Schasinglulu /*******************************************************************************
179*91f16700Schasinglulu  * Gets SPSR for BL33 entry
180*91f16700Schasinglulu  ******************************************************************************/
181*91f16700Schasinglulu static uint32_t qemu_get_spsr_for_bl33_entry(void)
182*91f16700Schasinglulu {
183*91f16700Schasinglulu 	uint32_t spsr;
184*91f16700Schasinglulu #ifdef __aarch64__
185*91f16700Schasinglulu 	unsigned int mode;
186*91f16700Schasinglulu 
187*91f16700Schasinglulu 	/* Figure out what mode we enter the non-secure world in */
188*91f16700Schasinglulu 	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
189*91f16700Schasinglulu 
190*91f16700Schasinglulu 	/*
191*91f16700Schasinglulu 	 * TODO: Consider the possibility of specifying the SPSR in
192*91f16700Schasinglulu 	 * the FIP ToC and allowing the platform to have a say as
193*91f16700Schasinglulu 	 * well.
194*91f16700Schasinglulu 	 */
195*91f16700Schasinglulu 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
196*91f16700Schasinglulu #else
197*91f16700Schasinglulu 	spsr = SPSR_MODE32(MODE32_svc,
198*91f16700Schasinglulu 		    plat_get_ns_image_entrypoint() & 0x1,
199*91f16700Schasinglulu 		    SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
200*91f16700Schasinglulu #endif
201*91f16700Schasinglulu 	return spsr;
202*91f16700Schasinglulu }
203*91f16700Schasinglulu 
204*91f16700Schasinglulu #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
205*91f16700Schasinglulu static int load_sps_from_tb_fw_config(struct image_info *image_info)
206*91f16700Schasinglulu {
207*91f16700Schasinglulu 	void *dtb = (void *)image_info->image_base;
208*91f16700Schasinglulu 	const char *compat_str = "arm,sp";
209*91f16700Schasinglulu 	const struct fdt_property *uuid;
210*91f16700Schasinglulu 	uint32_t load_addr;
211*91f16700Schasinglulu 	const char *name;
212*91f16700Schasinglulu 	int sp_node;
213*91f16700Schasinglulu 	int node;
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	node = fdt_node_offset_by_compatible(dtb, -1, compat_str);
216*91f16700Schasinglulu 	if (node < 0) {
217*91f16700Schasinglulu 		ERROR("Can't find %s in TB_FW_CONFIG", compat_str);
218*91f16700Schasinglulu 		return -1;
219*91f16700Schasinglulu 	}
220*91f16700Schasinglulu 
221*91f16700Schasinglulu 	fdt_for_each_subnode(sp_node, dtb, node) {
222*91f16700Schasinglulu 		name = fdt_get_name(dtb, sp_node, NULL);
223*91f16700Schasinglulu 		if (name == NULL) {
224*91f16700Schasinglulu 			ERROR("Can't get name of node in dtb\n");
225*91f16700Schasinglulu 			return -1;
226*91f16700Schasinglulu 		}
227*91f16700Schasinglulu 		uuid = fdt_get_property(dtb, sp_node, "uuid", NULL);
228*91f16700Schasinglulu 		if (uuid == NULL) {
229*91f16700Schasinglulu 			ERROR("Can't find property uuid in node %s", name);
230*91f16700Schasinglulu 			return -1;
231*91f16700Schasinglulu 		}
232*91f16700Schasinglulu 		if (fdt_read_uint32(dtb, sp_node, "load-address",
233*91f16700Schasinglulu 				    &load_addr) < 0) {
234*91f16700Schasinglulu 			ERROR("Can't read load-address in node %s", name);
235*91f16700Schasinglulu 			return -1;
236*91f16700Schasinglulu 		}
237*91f16700Schasinglulu 		if (qemu_io_register_sp_pkg(name, uuid->data, load_addr) < 0) {
238*91f16700Schasinglulu 			return -1;
239*91f16700Schasinglulu 		}
240*91f16700Schasinglulu 	}
241*91f16700Schasinglulu 
242*91f16700Schasinglulu 	return 0;
243*91f16700Schasinglulu }
244*91f16700Schasinglulu #endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
245*91f16700Schasinglulu 
246*91f16700Schasinglulu static int qemu_bl2_handle_post_image_load(unsigned int image_id)
247*91f16700Schasinglulu {
248*91f16700Schasinglulu 	int err = 0;
249*91f16700Schasinglulu 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
250*91f16700Schasinglulu #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
251*91f16700Schasinglulu 	bl_mem_params_node_t *pager_mem_params = NULL;
252*91f16700Schasinglulu 	bl_mem_params_node_t *paged_mem_params = NULL;
253*91f16700Schasinglulu #endif
254*91f16700Schasinglulu #if defined(SPD_spmd)
255*91f16700Schasinglulu 	bl_mem_params_node_t *bl32_mem_params = NULL;
256*91f16700Schasinglulu #endif
257*91f16700Schasinglulu #if TRANSFER_LIST
258*91f16700Schasinglulu 	struct transfer_list_header *ns_tl = NULL;
259*91f16700Schasinglulu 	struct transfer_list_entry *te = NULL;
260*91f16700Schasinglulu #endif
261*91f16700Schasinglulu 
262*91f16700Schasinglulu 	assert(bl_mem_params);
263*91f16700Schasinglulu 
264*91f16700Schasinglulu 	switch (image_id) {
265*91f16700Schasinglulu 	case BL32_IMAGE_ID:
266*91f16700Schasinglulu #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
267*91f16700Schasinglulu 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
268*91f16700Schasinglulu 		assert(pager_mem_params);
269*91f16700Schasinglulu 
270*91f16700Schasinglulu 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
271*91f16700Schasinglulu 		assert(paged_mem_params);
272*91f16700Schasinglulu 
273*91f16700Schasinglulu 		err = parse_optee_header(&bl_mem_params->ep_info,
274*91f16700Schasinglulu 					 &pager_mem_params->image_info,
275*91f16700Schasinglulu 					 &paged_mem_params->image_info);
276*91f16700Schasinglulu 		if (err != 0) {
277*91f16700Schasinglulu 			WARN("OPTEE header parse error.\n");
278*91f16700Schasinglulu 		}
279*91f16700Schasinglulu #endif
280*91f16700Schasinglulu 
281*91f16700Schasinglulu #if defined(SPMC_OPTEE)
282*91f16700Schasinglulu 		/*
283*91f16700Schasinglulu 		 * Explicit zeroes to unused registers since they may have
284*91f16700Schasinglulu 		 * been populated by parse_optee_header() above.
285*91f16700Schasinglulu 		 *
286*91f16700Schasinglulu 		 * OP-TEE expects system DTB in x2 and TOS_FW_CONFIG in x0,
287*91f16700Schasinglulu 		 * the latter is filled in below for TOS_FW_CONFIG_ID and
288*91f16700Schasinglulu 		 * applies to any other SPMC too.
289*91f16700Schasinglulu 		 */
290*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
291*91f16700Schasinglulu #elif defined(SPD_opteed)
292*91f16700Schasinglulu 		/*
293*91f16700Schasinglulu 		 * OP-TEE expect to receive DTB address in x2.
294*91f16700Schasinglulu 		 * This will be copied into x2 by dispatcher.
295*91f16700Schasinglulu 		 */
296*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg3 = ARM_PRELOADED_DTB_BASE;
297*91f16700Schasinglulu #elif defined(AARCH32_SP_OPTEE)
298*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg0 =
299*91f16700Schasinglulu 					bl_mem_params->ep_info.args.arg1;
300*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg1 = 0;
301*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
302*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg3 = 0;
303*91f16700Schasinglulu #endif
304*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
305*91f16700Schasinglulu 		break;
306*91f16700Schasinglulu 
307*91f16700Schasinglulu 	case BL33_IMAGE_ID:
308*91f16700Schasinglulu #ifdef AARCH32_SP_OPTEE
309*91f16700Schasinglulu 		/* AArch32 only core: OP-TEE expects NSec EP in register LR */
310*91f16700Schasinglulu 		pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
311*91f16700Schasinglulu 		assert(pager_mem_params);
312*91f16700Schasinglulu 		pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
313*91f16700Schasinglulu #endif
314*91f16700Schasinglulu 
315*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
316*91f16700Schasinglulu 
317*91f16700Schasinglulu #if ARM_LINUX_KERNEL_AS_BL33
318*91f16700Schasinglulu 		/*
319*91f16700Schasinglulu 		 * According to the file ``Documentation/arm64/booting.txt`` of
320*91f16700Schasinglulu 		 * the Linux kernel tree, Linux expects the physical address of
321*91f16700Schasinglulu 		 * the device tree blob (DTB) in x0, while x1-x3 are reserved
322*91f16700Schasinglulu 		 * for future use and must be 0.
323*91f16700Schasinglulu 		 */
324*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg0 =
325*91f16700Schasinglulu 			(u_register_t)ARM_PRELOADED_DTB_BASE;
326*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg1 = 0U;
327*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg2 = 0U;
328*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg3 = 0U;
329*91f16700Schasinglulu #elif TRANSFER_LIST
330*91f16700Schasinglulu 		if (bl2_tl) {
331*91f16700Schasinglulu 			// relocate the tl to pre-allocate NS memory
332*91f16700Schasinglulu 			ns_tl = transfer_list_relocate(bl2_tl,
333*91f16700Schasinglulu 					(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
334*91f16700Schasinglulu 					bl2_tl->max_size);
335*91f16700Schasinglulu 			if (!ns_tl) {
336*91f16700Schasinglulu 				ERROR("Relocate TL to 0x%lx failed\n",
337*91f16700Schasinglulu 					(unsigned long)FW_NS_HANDOFF_BASE);
338*91f16700Schasinglulu 				return -1;
339*91f16700Schasinglulu 			}
340*91f16700Schasinglulu 			NOTICE("Transfer list handoff to BL33\n");
341*91f16700Schasinglulu 			transfer_list_dump(ns_tl);
342*91f16700Schasinglulu 
343*91f16700Schasinglulu 			te = transfer_list_find(ns_tl, TL_TAG_FDT);
344*91f16700Schasinglulu 
345*91f16700Schasinglulu 			bl_mem_params->ep_info.args.arg1 =
346*91f16700Schasinglulu 				TRANSFER_LIST_SIGNATURE |
347*91f16700Schasinglulu 				REGISTER_CONVENTION_VERSION_MASK;
348*91f16700Schasinglulu 			bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
349*91f16700Schasinglulu 
350*91f16700Schasinglulu 			if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
351*91f16700Schasinglulu 				// aarch32
352*91f16700Schasinglulu 				bl_mem_params->ep_info.args.arg0 = 0;
353*91f16700Schasinglulu 				bl_mem_params->ep_info.args.arg2 = te ?
354*91f16700Schasinglulu 					(uintptr_t)transfer_list_entry_data(te)
355*91f16700Schasinglulu 					: 0;
356*91f16700Schasinglulu 			} else {
357*91f16700Schasinglulu 				// aarch64
358*91f16700Schasinglulu 				bl_mem_params->ep_info.args.arg0 = te ?
359*91f16700Schasinglulu 					(uintptr_t)transfer_list_entry_data(te)
360*91f16700Schasinglulu 					: 0;
361*91f16700Schasinglulu 				bl_mem_params->ep_info.args.arg2 = 0;
362*91f16700Schasinglulu 			}
363*91f16700Schasinglulu 		} else {
364*91f16700Schasinglulu 			// Legacy handoff
365*91f16700Schasinglulu 			bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
366*91f16700Schasinglulu 		}
367*91f16700Schasinglulu #else
368*91f16700Schasinglulu 		/* BL33 expects to receive the primary CPU MPID (through r0) */
369*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
370*91f16700Schasinglulu #endif // ARM_LINUX_KERNEL_AS_BL33
371*91f16700Schasinglulu 
372*91f16700Schasinglulu 		break;
373*91f16700Schasinglulu #ifdef SPD_spmd
374*91f16700Schasinglulu #if SPMD_SPM_AT_SEL2
375*91f16700Schasinglulu 	case TB_FW_CONFIG_ID:
376*91f16700Schasinglulu 		err = load_sps_from_tb_fw_config(&bl_mem_params->image_info);
377*91f16700Schasinglulu 		break;
378*91f16700Schasinglulu #endif
379*91f16700Schasinglulu 	case TOS_FW_CONFIG_ID:
380*91f16700Schasinglulu 		/* An SPMC expects TOS_FW_CONFIG in x0/r0 */
381*91f16700Schasinglulu 		bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
382*91f16700Schasinglulu 		bl32_mem_params->ep_info.args.arg0 =
383*91f16700Schasinglulu 					bl_mem_params->image_info.image_base;
384*91f16700Schasinglulu 		break;
385*91f16700Schasinglulu #endif
386*91f16700Schasinglulu 	default:
387*91f16700Schasinglulu 		/* Do nothing in default case */
388*91f16700Schasinglulu 		break;
389*91f16700Schasinglulu 	}
390*91f16700Schasinglulu 
391*91f16700Schasinglulu 	return err;
392*91f16700Schasinglulu }
393*91f16700Schasinglulu 
394*91f16700Schasinglulu /*******************************************************************************
395*91f16700Schasinglulu  * This function can be used by the platforms to update/use image
396*91f16700Schasinglulu  * information for given `image_id`.
397*91f16700Schasinglulu  ******************************************************************************/
398*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id)
399*91f16700Schasinglulu {
400*91f16700Schasinglulu 	return qemu_bl2_handle_post_image_load(image_id);
401*91f16700Schasinglulu }
402*91f16700Schasinglulu 
403*91f16700Schasinglulu uintptr_t plat_get_ns_image_entrypoint(void)
404*91f16700Schasinglulu {
405*91f16700Schasinglulu 	return NS_IMAGE_OFFSET;
406*91f16700Schasinglulu }
407