xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_bl2_setup.c (revision 2de0c5cc4fac47dcc5df295bd1eaf3a6da528424)
17cb09cb4SHaojian Zhuang /*
27cb09cb4SHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
37cb09cb4SHaojian Zhuang  *
47cb09cb4SHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
57cb09cb4SHaojian Zhuang  */
67cb09cb4SHaojian Zhuang 
77cb09cb4SHaojian Zhuang #include <arch_helpers.h>
87cb09cb4SHaojian Zhuang #include <assert.h>
97cb09cb4SHaojian Zhuang #include <bl_common.h>
107cb09cb4SHaojian Zhuang #include <console.h>
117cb09cb4SHaojian Zhuang #include <debug.h>
12*2de0c5ccSVictor Chong #include <desc_image_load.h>
137cb09cb4SHaojian Zhuang #include <errno.h>
147cb09cb4SHaojian Zhuang #include <generic_delay_timer.h>
157cb09cb4SHaojian Zhuang #include <hi3660.h>
167cb09cb4SHaojian Zhuang #include <mmio.h>
177cb09cb4SHaojian Zhuang #include <platform_def.h>
187cb09cb4SHaojian Zhuang #include <string.h>
197cb09cb4SHaojian Zhuang #include <ufs.h>
207cb09cb4SHaojian Zhuang 
217cb09cb4SHaojian Zhuang #include "hikey960_def.h"
227cb09cb4SHaojian Zhuang #include "hikey960_private.h"
237cb09cb4SHaojian Zhuang 
247cb09cb4SHaojian Zhuang /*
257cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the code & RO data region.
267cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
277cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
287cb09cb4SHaojian Zhuang  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
297cb09cb4SHaojian Zhuang  */
307cb09cb4SHaojian Zhuang #define BL2_RO_BASE (unsigned long)(&__RO_START__)
317cb09cb4SHaojian Zhuang #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
327cb09cb4SHaojian Zhuang 
337cb09cb4SHaojian Zhuang /*
347cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the coherent memory region.
357cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
367cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
377cb09cb4SHaojian Zhuang  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
387cb09cb4SHaojian Zhuang  * page-aligned addresses.
397cb09cb4SHaojian Zhuang  */
407cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
417cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
427cb09cb4SHaojian Zhuang 
437cb09cb4SHaojian Zhuang static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
447cb09cb4SHaojian Zhuang 
45*2de0c5ccSVictor Chong #if !LOAD_IMAGE_V2
46*2de0c5ccSVictor Chong 
47*2de0c5ccSVictor Chong /*******************************************************************************
48*2de0c5ccSVictor Chong  * This structure represents the superset of information that is passed to
49*2de0c5ccSVictor Chong  * BL31, e.g. while passing control to it from BL2, bl31_params
50*2de0c5ccSVictor Chong  * and other platform specific params
51*2de0c5ccSVictor Chong  ******************************************************************************/
527cb09cb4SHaojian Zhuang typedef struct bl2_to_bl31_params_mem {
537cb09cb4SHaojian Zhuang 	bl31_params_t		bl31_params;
547cb09cb4SHaojian Zhuang 	image_info_t		bl31_image_info;
557cb09cb4SHaojian Zhuang 	image_info_t		bl32_image_info;
567cb09cb4SHaojian Zhuang 	image_info_t		bl33_image_info;
577cb09cb4SHaojian Zhuang 	entry_point_info_t	bl33_ep_info;
587cb09cb4SHaojian Zhuang 	entry_point_info_t	bl32_ep_info;
597cb09cb4SHaojian Zhuang 	entry_point_info_t	bl31_ep_info;
607cb09cb4SHaojian Zhuang } bl2_to_bl31_params_mem_t;
617cb09cb4SHaojian Zhuang 
627cb09cb4SHaojian Zhuang static bl2_to_bl31_params_mem_t bl31_params_mem;
637cb09cb4SHaojian Zhuang 
647cb09cb4SHaojian Zhuang meminfo_t *bl2_plat_sec_mem_layout(void)
657cb09cb4SHaojian Zhuang {
667cb09cb4SHaojian Zhuang 	return &bl2_tzram_layout;
677cb09cb4SHaojian Zhuang }
687cb09cb4SHaojian Zhuang 
697cb09cb4SHaojian Zhuang bl31_params_t *bl2_plat_get_bl31_params(void)
707cb09cb4SHaojian Zhuang {
717cb09cb4SHaojian Zhuang 	bl31_params_t *bl2_to_bl31_params = NULL;
727cb09cb4SHaojian Zhuang 
737cb09cb4SHaojian Zhuang 	/*
747cb09cb4SHaojian Zhuang 	 * Initialise the memory for all the arguments that needs to
757cb09cb4SHaojian Zhuang 	 * be passed to BL3-1
767cb09cb4SHaojian Zhuang 	 */
777cb09cb4SHaojian Zhuang 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
787cb09cb4SHaojian Zhuang 
797cb09cb4SHaojian Zhuang 	/* Assign memory for TF related information */
807cb09cb4SHaojian Zhuang 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
817cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
827cb09cb4SHaojian Zhuang 
837cb09cb4SHaojian Zhuang 	/* Fill BL3-1 related information */
847cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
857cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
867cb09cb4SHaojian Zhuang 		VERSION_1, 0);
877cb09cb4SHaojian Zhuang 
887cb09cb4SHaojian Zhuang 	/* Fill BL3-2 related information if it exists */
897cb09cb4SHaojian Zhuang #if BL32_BASE
907cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
917cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
927cb09cb4SHaojian Zhuang 		VERSION_1, 0);
937cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
947cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
957cb09cb4SHaojian Zhuang 		VERSION_1, 0);
967cb09cb4SHaojian Zhuang #endif
977cb09cb4SHaojian Zhuang 
987cb09cb4SHaojian Zhuang 	/* Fill BL3-3 related information */
997cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
1007cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
1017cb09cb4SHaojian Zhuang 		PARAM_EP, VERSION_1, 0);
1027cb09cb4SHaojian Zhuang 
1037cb09cb4SHaojian Zhuang 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
1047cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
1057cb09cb4SHaojian Zhuang 
1067cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
1077cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
1087cb09cb4SHaojian Zhuang 		VERSION_1, 0);
1097cb09cb4SHaojian Zhuang 
1107cb09cb4SHaojian Zhuang 	return bl2_to_bl31_params;
1117cb09cb4SHaojian Zhuang }
1127cb09cb4SHaojian Zhuang 
1137cb09cb4SHaojian Zhuang /*******************************************************************************
1147cb09cb4SHaojian Zhuang  * Populate the extents of memory available for loading SCP_BL2 (if used),
1157cb09cb4SHaojian Zhuang  * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
1167cb09cb4SHaojian Zhuang  ******************************************************************************/
1177cb09cb4SHaojian Zhuang void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
1187cb09cb4SHaojian Zhuang {
119*2de0c5ccSVictor Chong 	hikey960_init_ufs();
1207cb09cb4SHaojian Zhuang 	hikey960_io_setup();
1217cb09cb4SHaojian Zhuang 
1227cb09cb4SHaojian Zhuang 	*scp_bl2_meminfo = bl2_tzram_layout;
1237cb09cb4SHaojian Zhuang }
124*2de0c5ccSVictor Chong #endif /* LOAD_IMAGE_V2 */
1257cb09cb4SHaojian Zhuang 
1267cb09cb4SHaojian Zhuang extern int load_lpm3(void);
1277cb09cb4SHaojian Zhuang 
128*2de0c5ccSVictor Chong /*******************************************************************************
129*2de0c5ccSVictor Chong  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
130*2de0c5ccSVictor Chong  * Return 0 on success, -1 otherwise.
131*2de0c5ccSVictor Chong  ******************************************************************************/
132*2de0c5ccSVictor Chong #if LOAD_IMAGE_V2
133*2de0c5ccSVictor Chong int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
134*2de0c5ccSVictor Chong #else
1357cb09cb4SHaojian Zhuang int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
136*2de0c5ccSVictor Chong #endif
1377cb09cb4SHaojian Zhuang {
1387cb09cb4SHaojian Zhuang 	int i;
1397cb09cb4SHaojian Zhuang 	int *buf;
1407cb09cb4SHaojian Zhuang 
141*2de0c5ccSVictor Chong 	assert(scp_bl2_image_info->image_size < SCP_BL2_SIZE);
1427cb09cb4SHaojian Zhuang 
1437cb09cb4SHaojian Zhuang 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
1447cb09cb4SHaojian Zhuang 
1457cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
1467cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_base,
1477cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_size);
1487cb09cb4SHaojian Zhuang 
1497cb09cb4SHaojian Zhuang 	buf = (int *)scp_bl2_image_info->image_base;
1507cb09cb4SHaojian Zhuang 
1517cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 HEAD:\n");
1527cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1537cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1547cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1557cb09cb4SHaojian Zhuang 
1567cb09cb4SHaojian Zhuang 	buf = (int *)(scp_bl2_image_info->image_base +
1577cb09cb4SHaojian Zhuang 		      scp_bl2_image_info->image_size - 256);
1587cb09cb4SHaojian Zhuang 
1597cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 TAIL:\n");
1607cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1617cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1627cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1637cb09cb4SHaojian Zhuang 
1647cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 transferred to SCP\n");
1657cb09cb4SHaojian Zhuang 
1667cb09cb4SHaojian Zhuang 	load_lpm3();
1677cb09cb4SHaojian Zhuang 	(void)buf;
1687cb09cb4SHaojian Zhuang 
1697cb09cb4SHaojian Zhuang 	return 0;
1707cb09cb4SHaojian Zhuang }
1717cb09cb4SHaojian Zhuang 
172*2de0c5ccSVictor Chong void hikey960_init_ufs(void)
173*2de0c5ccSVictor Chong {
174*2de0c5ccSVictor Chong 	ufs_params_t ufs_params;
175*2de0c5ccSVictor Chong 
176*2de0c5ccSVictor Chong 	memset(&ufs_params, 0, sizeof(ufs_params_t));
177*2de0c5ccSVictor Chong 	ufs_params.reg_base = UFS_REG_BASE;
178*2de0c5ccSVictor Chong 	ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
179*2de0c5ccSVictor Chong 	ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
180*2de0c5ccSVictor Chong 	ufs_params.flags = UFS_FLAGS_SKIPINIT;
181*2de0c5ccSVictor Chong 	ufs_init(NULL, &ufs_params);
182*2de0c5ccSVictor Chong }
183*2de0c5ccSVictor Chong 
184*2de0c5ccSVictor Chong /*******************************************************************************
185*2de0c5ccSVictor Chong  * Gets SPSR for BL32 entry
186*2de0c5ccSVictor Chong  ******************************************************************************/
187*2de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl32_entry(void)
188*2de0c5ccSVictor Chong {
189*2de0c5ccSVictor Chong 	/*
190*2de0c5ccSVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
191*2de0c5ccSVictor Chong 	 * setting the SPSR prior to entry into the BL3-2 image.
192*2de0c5ccSVictor Chong 	 */
193*2de0c5ccSVictor Chong 	return 0;
194*2de0c5ccSVictor Chong }
195*2de0c5ccSVictor Chong 
196*2de0c5ccSVictor Chong /*******************************************************************************
197*2de0c5ccSVictor Chong  * Gets SPSR for BL33 entry
198*2de0c5ccSVictor Chong  ******************************************************************************/
199*2de0c5ccSVictor Chong #ifndef AARCH32
200*2de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl33_entry(void)
201*2de0c5ccSVictor Chong {
202*2de0c5ccSVictor Chong 	unsigned int mode;
203*2de0c5ccSVictor Chong 	uint32_t spsr;
204*2de0c5ccSVictor Chong 
205*2de0c5ccSVictor Chong 	/* Figure out what mode we enter the non-secure world in */
206*2de0c5ccSVictor Chong 	mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
207*2de0c5ccSVictor Chong 
208*2de0c5ccSVictor Chong 	/*
209*2de0c5ccSVictor Chong 	 * TODO: Consider the possibility of specifying the SPSR in
210*2de0c5ccSVictor Chong 	 * the FIP ToC and allowing the platform to have a say as
211*2de0c5ccSVictor Chong 	 * well.
212*2de0c5ccSVictor Chong 	 */
213*2de0c5ccSVictor Chong 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
214*2de0c5ccSVictor Chong 	return spsr;
215*2de0c5ccSVictor Chong }
216*2de0c5ccSVictor Chong #else
217*2de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl33_entry(void)
218*2de0c5ccSVictor Chong {
219*2de0c5ccSVictor Chong 	unsigned int hyp_status, mode, spsr;
220*2de0c5ccSVictor Chong 
221*2de0c5ccSVictor Chong 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
222*2de0c5ccSVictor Chong 
223*2de0c5ccSVictor Chong 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
224*2de0c5ccSVictor Chong 
225*2de0c5ccSVictor Chong 	/*
226*2de0c5ccSVictor Chong 	 * TODO: Consider the possibility of specifying the SPSR in
227*2de0c5ccSVictor Chong 	 * the FIP ToC and allowing the platform to have a say as
228*2de0c5ccSVictor Chong 	 * well.
229*2de0c5ccSVictor Chong 	 */
230*2de0c5ccSVictor Chong 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
231*2de0c5ccSVictor Chong 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
232*2de0c5ccSVictor Chong 	return spsr;
233*2de0c5ccSVictor Chong }
234*2de0c5ccSVictor Chong #endif /* AARCH32 */
235*2de0c5ccSVictor Chong 
236*2de0c5ccSVictor Chong #if LOAD_IMAGE_V2
237*2de0c5ccSVictor Chong int hikey960_bl2_handle_post_image_load(unsigned int image_id)
238*2de0c5ccSVictor Chong {
239*2de0c5ccSVictor Chong 	int err = 0;
240*2de0c5ccSVictor Chong 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
241*2de0c5ccSVictor Chong 	assert(bl_mem_params);
242*2de0c5ccSVictor Chong 
243*2de0c5ccSVictor Chong 	switch (image_id) {
244*2de0c5ccSVictor Chong #ifdef AARCH64
245*2de0c5ccSVictor Chong 	case BL32_IMAGE_ID:
246*2de0c5ccSVictor Chong 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl32_entry();
247*2de0c5ccSVictor Chong 		break;
248*2de0c5ccSVictor Chong #endif
249*2de0c5ccSVictor Chong 
250*2de0c5ccSVictor Chong 	case BL33_IMAGE_ID:
251*2de0c5ccSVictor Chong 		/* BL33 expects to receive the primary CPU MPID (through r0) */
252*2de0c5ccSVictor Chong 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
253*2de0c5ccSVictor Chong 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl33_entry();
254*2de0c5ccSVictor Chong 		break;
255*2de0c5ccSVictor Chong 
256*2de0c5ccSVictor Chong #ifdef SCP_BL2_BASE
257*2de0c5ccSVictor Chong 	case SCP_BL2_IMAGE_ID:
258*2de0c5ccSVictor Chong 		/* The subsequent handling of SCP_BL2 is platform specific */
259*2de0c5ccSVictor Chong 		err = plat_hikey960_bl2_handle_scp_bl2(&bl_mem_params->image_info);
260*2de0c5ccSVictor Chong 		if (err) {
261*2de0c5ccSVictor Chong 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
262*2de0c5ccSVictor Chong 		}
263*2de0c5ccSVictor Chong 		break;
264*2de0c5ccSVictor Chong #endif
265*2de0c5ccSVictor Chong 	}
266*2de0c5ccSVictor Chong 
267*2de0c5ccSVictor Chong 	return err;
268*2de0c5ccSVictor Chong }
269*2de0c5ccSVictor Chong 
270*2de0c5ccSVictor Chong /*******************************************************************************
271*2de0c5ccSVictor Chong  * This function can be used by the platforms to update/use image
272*2de0c5ccSVictor Chong  * information for given `image_id`.
273*2de0c5ccSVictor Chong  ******************************************************************************/
274*2de0c5ccSVictor Chong int bl2_plat_handle_post_image_load(unsigned int image_id)
275*2de0c5ccSVictor Chong {
276*2de0c5ccSVictor Chong 	return hikey960_bl2_handle_post_image_load(image_id);
277*2de0c5ccSVictor Chong }
278*2de0c5ccSVictor Chong 
279*2de0c5ccSVictor Chong #else /* LOAD_IMAGE_V2 */
280*2de0c5ccSVictor Chong 
2817cb09cb4SHaojian Zhuang struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
2827cb09cb4SHaojian Zhuang {
283*2de0c5ccSVictor Chong #if DEBUG
284*2de0c5ccSVictor Chong 	bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL;
285*2de0c5ccSVictor Chong #endif
286*2de0c5ccSVictor Chong 
2877cb09cb4SHaojian Zhuang 	return &bl31_params_mem.bl31_ep_info;
2887cb09cb4SHaojian Zhuang }
2897cb09cb4SHaojian Zhuang 
2907cb09cb4SHaojian Zhuang void bl2_plat_set_bl31_ep_info(image_info_t *image,
2917cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl31_ep_info)
2927cb09cb4SHaojian Zhuang {
2937cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
2947cb09cb4SHaojian Zhuang 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
2957cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
2967cb09cb4SHaojian Zhuang }
2977cb09cb4SHaojian Zhuang 
2985e3325e7SVictor Chong /*******************************************************************************
2995e3325e7SVictor Chong  * Before calling this function BL32 is loaded in memory and its entrypoint
3005e3325e7SVictor Chong  * is set by load_image. This is a placeholder for the platform to change
3015e3325e7SVictor Chong  * the entrypoint of BL32 and set SPSR and security state.
3025e3325e7SVictor Chong  * On Hikey we only set the security state of the entrypoint
3035e3325e7SVictor Chong  ******************************************************************************/
3045e3325e7SVictor Chong #ifdef BL32_BASE
3055e3325e7SVictor Chong void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
3065e3325e7SVictor Chong 					entry_point_info_t *bl32_ep_info)
3075e3325e7SVictor Chong {
3085e3325e7SVictor Chong 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
3095e3325e7SVictor Chong 	/*
3105e3325e7SVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
3115e3325e7SVictor Chong 	 * setting the SPSR prior to entry into the BL32 image.
3125e3325e7SVictor Chong 	 */
3135e3325e7SVictor Chong 	bl32_ep_info->spsr = 0;
3145e3325e7SVictor Chong }
3155e3325e7SVictor Chong 
3165e3325e7SVictor Chong /*******************************************************************************
3175e3325e7SVictor Chong  * Populate the extents of memory available for loading BL32
3185e3325e7SVictor Chong  ******************************************************************************/
3195e3325e7SVictor Chong void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
3205e3325e7SVictor Chong {
3215e3325e7SVictor Chong 	/*
3225e3325e7SVictor Chong 	 * Populate the extents of memory available for loading BL32.
3235e3325e7SVictor Chong 	 */
3245e3325e7SVictor Chong 	bl32_meminfo->total_base = BL32_BASE;
3255e3325e7SVictor Chong 	bl32_meminfo->free_base = BL32_BASE;
3265e3325e7SVictor Chong 	bl32_meminfo->total_size =
3275e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
3285e3325e7SVictor Chong 	bl32_meminfo->free_size =
3295e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
3305e3325e7SVictor Chong }
3315e3325e7SVictor Chong #endif /* BL32_BASE */
3325e3325e7SVictor Chong 
3337cb09cb4SHaojian Zhuang void bl2_plat_set_bl33_ep_info(image_info_t *image,
3347cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl33_ep_info)
3357cb09cb4SHaojian Zhuang {
3367cb09cb4SHaojian Zhuang 	unsigned long el_status;
3377cb09cb4SHaojian Zhuang 	unsigned int mode;
3387cb09cb4SHaojian Zhuang 
3397cb09cb4SHaojian Zhuang 	/* Figure out what mode we enter the non-secure world in */
3407cb09cb4SHaojian Zhuang 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
3417cb09cb4SHaojian Zhuang 	el_status &= ID_AA64PFR0_ELX_MASK;
3427cb09cb4SHaojian Zhuang 
3437cb09cb4SHaojian Zhuang 	if (el_status)
3447cb09cb4SHaojian Zhuang 		mode = MODE_EL2;
3457cb09cb4SHaojian Zhuang 	else
3467cb09cb4SHaojian Zhuang 		mode = MODE_EL1;
3477cb09cb4SHaojian Zhuang 
3487cb09cb4SHaojian Zhuang 	/*
3497cb09cb4SHaojian Zhuang 	 * TODO: Consider the possibility of specifying the SPSR in
3507cb09cb4SHaojian Zhuang 	 * the FIP ToC and allowing the platform to have a say as
3517cb09cb4SHaojian Zhuang 	 * well.
3527cb09cb4SHaojian Zhuang 	 */
3537cb09cb4SHaojian Zhuang 	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
3547cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
3557cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
3567cb09cb4SHaojian Zhuang }
3577cb09cb4SHaojian Zhuang 
3587cb09cb4SHaojian Zhuang void bl2_plat_flush_bl31_params(void)
3597cb09cb4SHaojian Zhuang {
3607cb09cb4SHaojian Zhuang 	flush_dcache_range((unsigned long)&bl31_params_mem,
3617cb09cb4SHaojian Zhuang 			   sizeof(bl2_to_bl31_params_mem_t));
3627cb09cb4SHaojian Zhuang }
3637cb09cb4SHaojian Zhuang 
3647cb09cb4SHaojian Zhuang void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
3657cb09cb4SHaojian Zhuang {
3667cb09cb4SHaojian Zhuang 	bl33_meminfo->total_base = DDR_BASE;
3677cb09cb4SHaojian Zhuang 	bl33_meminfo->total_size = DDR_SIZE;
3687cb09cb4SHaojian Zhuang 	bl33_meminfo->free_base = DDR_BASE;
3697cb09cb4SHaojian Zhuang 	bl33_meminfo->free_size = DDR_SIZE;
3707cb09cb4SHaojian Zhuang }
371*2de0c5ccSVictor Chong #endif /* LOAD_IMAGE_V2 */
3727cb09cb4SHaojian Zhuang 
3737cb09cb4SHaojian Zhuang void bl2_early_platform_setup(meminfo_t *mem_layout)
3747cb09cb4SHaojian Zhuang {
3757cb09cb4SHaojian Zhuang 	unsigned int id, uart_base;
3767cb09cb4SHaojian Zhuang 
3777cb09cb4SHaojian Zhuang 	generic_delay_timer_init();
3787cb09cb4SHaojian Zhuang 	hikey960_read_boardid(&id);
3797cb09cb4SHaojian Zhuang 	if (id == 5300)
3807cb09cb4SHaojian Zhuang 		uart_base = PL011_UART5_BASE;
3817cb09cb4SHaojian Zhuang 	else
3827cb09cb4SHaojian Zhuang 		uart_base = PL011_UART6_BASE;
3837cb09cb4SHaojian Zhuang 
3847cb09cb4SHaojian Zhuang 	/* Initialize the console to provide early debug support */
3857cb09cb4SHaojian Zhuang 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
3867cb09cb4SHaojian Zhuang 
3877cb09cb4SHaojian Zhuang 	/* Setup the BL2 memory layout */
3887cb09cb4SHaojian Zhuang 	bl2_tzram_layout = *mem_layout;
3897cb09cb4SHaojian Zhuang }
3907cb09cb4SHaojian Zhuang 
3917cb09cb4SHaojian Zhuang void bl2_plat_arch_setup(void)
3927cb09cb4SHaojian Zhuang {
3937cb09cb4SHaojian Zhuang 	hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
3947cb09cb4SHaojian Zhuang 			      bl2_tzram_layout.total_size,
3957cb09cb4SHaojian Zhuang 			      BL2_RO_BASE,
3967cb09cb4SHaojian Zhuang 			      BL2_RO_LIMIT,
3977cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_BASE,
3987cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_LIMIT);
3997cb09cb4SHaojian Zhuang }
4007cb09cb4SHaojian Zhuang 
4017cb09cb4SHaojian Zhuang void bl2_platform_setup(void)
4027cb09cb4SHaojian Zhuang {
4037cb09cb4SHaojian Zhuang 	/* disable WDT0 */
4047cb09cb4SHaojian Zhuang 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
4057cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
4067cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
4077cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
4087cb09cb4SHaojian Zhuang 	}
4097cb09cb4SHaojian Zhuang }
410