xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_bl2_setup.c (revision b16bb16e3b6423929c2b2a7c23486ef538cca6aa)
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>
122de0c5ccSVictor 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>
17*b16bb16eSVictor Chong #if LOAD_IMAGE_V2
18*b16bb16eSVictor Chong #ifdef SPD_opteed
19*b16bb16eSVictor Chong #include <optee_utils.h>
20*b16bb16eSVictor Chong #endif
21*b16bb16eSVictor Chong #endif
227cb09cb4SHaojian Zhuang #include <platform_def.h>
237cb09cb4SHaojian Zhuang #include <string.h>
247cb09cb4SHaojian Zhuang #include <ufs.h>
257cb09cb4SHaojian Zhuang 
267cb09cb4SHaojian Zhuang #include "hikey960_def.h"
277cb09cb4SHaojian Zhuang #include "hikey960_private.h"
287cb09cb4SHaojian Zhuang 
297cb09cb4SHaojian Zhuang /*
307cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the code & RO data region.
317cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
327cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
337cb09cb4SHaojian Zhuang  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
347cb09cb4SHaojian Zhuang  */
357cb09cb4SHaojian Zhuang #define BL2_RO_BASE (unsigned long)(&__RO_START__)
367cb09cb4SHaojian Zhuang #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
377cb09cb4SHaojian Zhuang 
387cb09cb4SHaojian Zhuang /*
397cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the coherent memory region.
407cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
417cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
427cb09cb4SHaojian Zhuang  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
437cb09cb4SHaojian Zhuang  * page-aligned addresses.
447cb09cb4SHaojian Zhuang  */
457cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
467cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
477cb09cb4SHaojian Zhuang 
487cb09cb4SHaojian Zhuang static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
497cb09cb4SHaojian Zhuang 
502de0c5ccSVictor Chong #if !LOAD_IMAGE_V2
512de0c5ccSVictor Chong 
522de0c5ccSVictor Chong /*******************************************************************************
532de0c5ccSVictor Chong  * This structure represents the superset of information that is passed to
542de0c5ccSVictor Chong  * BL31, e.g. while passing control to it from BL2, bl31_params
552de0c5ccSVictor Chong  * and other platform specific params
562de0c5ccSVictor Chong  ******************************************************************************/
577cb09cb4SHaojian Zhuang typedef struct bl2_to_bl31_params_mem {
587cb09cb4SHaojian Zhuang 	bl31_params_t		bl31_params;
597cb09cb4SHaojian Zhuang 	image_info_t		bl31_image_info;
607cb09cb4SHaojian Zhuang 	image_info_t		bl32_image_info;
617cb09cb4SHaojian Zhuang 	image_info_t		bl33_image_info;
627cb09cb4SHaojian Zhuang 	entry_point_info_t	bl33_ep_info;
637cb09cb4SHaojian Zhuang 	entry_point_info_t	bl32_ep_info;
647cb09cb4SHaojian Zhuang 	entry_point_info_t	bl31_ep_info;
657cb09cb4SHaojian Zhuang } bl2_to_bl31_params_mem_t;
667cb09cb4SHaojian Zhuang 
677cb09cb4SHaojian Zhuang static bl2_to_bl31_params_mem_t bl31_params_mem;
687cb09cb4SHaojian Zhuang 
697cb09cb4SHaojian Zhuang meminfo_t *bl2_plat_sec_mem_layout(void)
707cb09cb4SHaojian Zhuang {
717cb09cb4SHaojian Zhuang 	return &bl2_tzram_layout;
727cb09cb4SHaojian Zhuang }
737cb09cb4SHaojian Zhuang 
747cb09cb4SHaojian Zhuang bl31_params_t *bl2_plat_get_bl31_params(void)
757cb09cb4SHaojian Zhuang {
767cb09cb4SHaojian Zhuang 	bl31_params_t *bl2_to_bl31_params = NULL;
777cb09cb4SHaojian Zhuang 
787cb09cb4SHaojian Zhuang 	/*
797cb09cb4SHaojian Zhuang 	 * Initialise the memory for all the arguments that needs to
807cb09cb4SHaojian Zhuang 	 * be passed to BL3-1
817cb09cb4SHaojian Zhuang 	 */
827cb09cb4SHaojian Zhuang 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
837cb09cb4SHaojian Zhuang 
847cb09cb4SHaojian Zhuang 	/* Assign memory for TF related information */
857cb09cb4SHaojian Zhuang 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
867cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
877cb09cb4SHaojian Zhuang 
887cb09cb4SHaojian Zhuang 	/* Fill BL3-1 related information */
897cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
907cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
917cb09cb4SHaojian Zhuang 		VERSION_1, 0);
927cb09cb4SHaojian Zhuang 
937cb09cb4SHaojian Zhuang 	/* Fill BL3-2 related information if it exists */
947cb09cb4SHaojian Zhuang #if BL32_BASE
957cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
967cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
977cb09cb4SHaojian Zhuang 		VERSION_1, 0);
987cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
997cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
1007cb09cb4SHaojian Zhuang 		VERSION_1, 0);
1017cb09cb4SHaojian Zhuang #endif
1027cb09cb4SHaojian Zhuang 
1037cb09cb4SHaojian Zhuang 	/* Fill BL3-3 related information */
1047cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
1057cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
1067cb09cb4SHaojian Zhuang 		PARAM_EP, VERSION_1, 0);
1077cb09cb4SHaojian Zhuang 
1087cb09cb4SHaojian Zhuang 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
1097cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
1107cb09cb4SHaojian Zhuang 
1117cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
1127cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
1137cb09cb4SHaojian Zhuang 		VERSION_1, 0);
1147cb09cb4SHaojian Zhuang 
1157cb09cb4SHaojian Zhuang 	return bl2_to_bl31_params;
1167cb09cb4SHaojian Zhuang }
1177cb09cb4SHaojian Zhuang 
1187cb09cb4SHaojian Zhuang /*******************************************************************************
1197cb09cb4SHaojian Zhuang  * Populate the extents of memory available for loading SCP_BL2 (if used),
1207cb09cb4SHaojian Zhuang  * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
1217cb09cb4SHaojian Zhuang  ******************************************************************************/
1227cb09cb4SHaojian Zhuang void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
1237cb09cb4SHaojian Zhuang {
1242de0c5ccSVictor Chong 	hikey960_init_ufs();
1257cb09cb4SHaojian Zhuang 	hikey960_io_setup();
1267cb09cb4SHaojian Zhuang 
1277cb09cb4SHaojian Zhuang 	*scp_bl2_meminfo = bl2_tzram_layout;
1287cb09cb4SHaojian Zhuang }
1292de0c5ccSVictor Chong #endif /* LOAD_IMAGE_V2 */
1307cb09cb4SHaojian Zhuang 
1317cb09cb4SHaojian Zhuang extern int load_lpm3(void);
1327cb09cb4SHaojian Zhuang 
1332de0c5ccSVictor Chong /*******************************************************************************
1342de0c5ccSVictor Chong  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
1352de0c5ccSVictor Chong  * Return 0 on success, -1 otherwise.
1362de0c5ccSVictor Chong  ******************************************************************************/
1372de0c5ccSVictor Chong #if LOAD_IMAGE_V2
1382de0c5ccSVictor Chong int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
1392de0c5ccSVictor Chong #else
1407cb09cb4SHaojian Zhuang int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
1412de0c5ccSVictor Chong #endif
1427cb09cb4SHaojian Zhuang {
1437cb09cb4SHaojian Zhuang 	int i;
1447cb09cb4SHaojian Zhuang 	int *buf;
1457cb09cb4SHaojian Zhuang 
1462de0c5ccSVictor Chong 	assert(scp_bl2_image_info->image_size < SCP_BL2_SIZE);
1477cb09cb4SHaojian Zhuang 
1487cb09cb4SHaojian Zhuang 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
1497cb09cb4SHaojian Zhuang 
1507cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
1517cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_base,
1527cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_size);
1537cb09cb4SHaojian Zhuang 
1547cb09cb4SHaojian Zhuang 	buf = (int *)scp_bl2_image_info->image_base;
1557cb09cb4SHaojian Zhuang 
1567cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 HEAD:\n");
1577cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1587cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1597cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1607cb09cb4SHaojian Zhuang 
1617cb09cb4SHaojian Zhuang 	buf = (int *)(scp_bl2_image_info->image_base +
1627cb09cb4SHaojian Zhuang 		      scp_bl2_image_info->image_size - 256);
1637cb09cb4SHaojian Zhuang 
1647cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 TAIL:\n");
1657cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1667cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1677cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1687cb09cb4SHaojian Zhuang 
1697cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 transferred to SCP\n");
1707cb09cb4SHaojian Zhuang 
1717cb09cb4SHaojian Zhuang 	load_lpm3();
1727cb09cb4SHaojian Zhuang 	(void)buf;
1737cb09cb4SHaojian Zhuang 
1747cb09cb4SHaojian Zhuang 	return 0;
1757cb09cb4SHaojian Zhuang }
1767cb09cb4SHaojian Zhuang 
1772de0c5ccSVictor Chong void hikey960_init_ufs(void)
1782de0c5ccSVictor Chong {
1792de0c5ccSVictor Chong 	ufs_params_t ufs_params;
1802de0c5ccSVictor Chong 
1812de0c5ccSVictor Chong 	memset(&ufs_params, 0, sizeof(ufs_params_t));
1822de0c5ccSVictor Chong 	ufs_params.reg_base = UFS_REG_BASE;
1832de0c5ccSVictor Chong 	ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
1842de0c5ccSVictor Chong 	ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
1852de0c5ccSVictor Chong 	ufs_params.flags = UFS_FLAGS_SKIPINIT;
1862de0c5ccSVictor Chong 	ufs_init(NULL, &ufs_params);
1872de0c5ccSVictor Chong }
1882de0c5ccSVictor Chong 
1892de0c5ccSVictor Chong /*******************************************************************************
1902de0c5ccSVictor Chong  * Gets SPSR for BL32 entry
1912de0c5ccSVictor Chong  ******************************************************************************/
1922de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl32_entry(void)
1932de0c5ccSVictor Chong {
1942de0c5ccSVictor Chong 	/*
1952de0c5ccSVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
1962de0c5ccSVictor Chong 	 * setting the SPSR prior to entry into the BL3-2 image.
1972de0c5ccSVictor Chong 	 */
1982de0c5ccSVictor Chong 	return 0;
1992de0c5ccSVictor Chong }
2002de0c5ccSVictor Chong 
2012de0c5ccSVictor Chong /*******************************************************************************
2022de0c5ccSVictor Chong  * Gets SPSR for BL33 entry
2032de0c5ccSVictor Chong  ******************************************************************************/
2042de0c5ccSVictor Chong #ifndef AARCH32
2052de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl33_entry(void)
2062de0c5ccSVictor Chong {
2072de0c5ccSVictor Chong 	unsigned int mode;
2082de0c5ccSVictor Chong 	uint32_t spsr;
2092de0c5ccSVictor Chong 
2102de0c5ccSVictor Chong 	/* Figure out what mode we enter the non-secure world in */
2112de0c5ccSVictor Chong 	mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
2122de0c5ccSVictor Chong 
2132de0c5ccSVictor Chong 	/*
2142de0c5ccSVictor Chong 	 * TODO: Consider the possibility of specifying the SPSR in
2152de0c5ccSVictor Chong 	 * the FIP ToC and allowing the platform to have a say as
2162de0c5ccSVictor Chong 	 * well.
2172de0c5ccSVictor Chong 	 */
2182de0c5ccSVictor Chong 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
2192de0c5ccSVictor Chong 	return spsr;
2202de0c5ccSVictor Chong }
2212de0c5ccSVictor Chong #else
2222de0c5ccSVictor Chong uint32_t hikey960_get_spsr_for_bl33_entry(void)
2232de0c5ccSVictor Chong {
2242de0c5ccSVictor Chong 	unsigned int hyp_status, mode, spsr;
2252de0c5ccSVictor Chong 
2262de0c5ccSVictor Chong 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
2272de0c5ccSVictor Chong 
2282de0c5ccSVictor Chong 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
2292de0c5ccSVictor Chong 
2302de0c5ccSVictor Chong 	/*
2312de0c5ccSVictor Chong 	 * TODO: Consider the possibility of specifying the SPSR in
2322de0c5ccSVictor Chong 	 * the FIP ToC and allowing the platform to have a say as
2332de0c5ccSVictor Chong 	 * well.
2342de0c5ccSVictor Chong 	 */
2352de0c5ccSVictor Chong 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
2362de0c5ccSVictor Chong 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
2372de0c5ccSVictor Chong 	return spsr;
2382de0c5ccSVictor Chong }
2392de0c5ccSVictor Chong #endif /* AARCH32 */
2402de0c5ccSVictor Chong 
2412de0c5ccSVictor Chong #if LOAD_IMAGE_V2
2422de0c5ccSVictor Chong int hikey960_bl2_handle_post_image_load(unsigned int image_id)
2432de0c5ccSVictor Chong {
2442de0c5ccSVictor Chong 	int err = 0;
2452de0c5ccSVictor Chong 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
246*b16bb16eSVictor Chong #ifdef SPD_opteed
247*b16bb16eSVictor Chong 	bl_mem_params_node_t *pager_mem_params = NULL;
248*b16bb16eSVictor Chong 	bl_mem_params_node_t *paged_mem_params = NULL;
249*b16bb16eSVictor Chong #endif
2502de0c5ccSVictor Chong 	assert(bl_mem_params);
2512de0c5ccSVictor Chong 
2522de0c5ccSVictor Chong 	switch (image_id) {
2532de0c5ccSVictor Chong #ifdef AARCH64
2542de0c5ccSVictor Chong 	case BL32_IMAGE_ID:
255*b16bb16eSVictor Chong #ifdef SPD_opteed
256*b16bb16eSVictor Chong 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
257*b16bb16eSVictor Chong 		assert(pager_mem_params);
258*b16bb16eSVictor Chong 
259*b16bb16eSVictor Chong 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
260*b16bb16eSVictor Chong 		assert(paged_mem_params);
261*b16bb16eSVictor Chong 
262*b16bb16eSVictor Chong 		err = parse_optee_header(&bl_mem_params->ep_info,
263*b16bb16eSVictor Chong 				&pager_mem_params->image_info,
264*b16bb16eSVictor Chong 				&paged_mem_params->image_info);
265*b16bb16eSVictor Chong 		if (err != 0) {
266*b16bb16eSVictor Chong 			WARN("OPTEE header parse error.\n");
267*b16bb16eSVictor Chong 		}
268*b16bb16eSVictor Chong #endif
2692de0c5ccSVictor Chong 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl32_entry();
2702de0c5ccSVictor Chong 		break;
2712de0c5ccSVictor Chong #endif
2722de0c5ccSVictor Chong 
2732de0c5ccSVictor Chong 	case BL33_IMAGE_ID:
2742de0c5ccSVictor Chong 		/* BL33 expects to receive the primary CPU MPID (through r0) */
2752de0c5ccSVictor Chong 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
2762de0c5ccSVictor Chong 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl33_entry();
2772de0c5ccSVictor Chong 		break;
2782de0c5ccSVictor Chong 
2792de0c5ccSVictor Chong #ifdef SCP_BL2_BASE
2802de0c5ccSVictor Chong 	case SCP_BL2_IMAGE_ID:
2812de0c5ccSVictor Chong 		/* The subsequent handling of SCP_BL2 is platform specific */
2822de0c5ccSVictor Chong 		err = plat_hikey960_bl2_handle_scp_bl2(&bl_mem_params->image_info);
2832de0c5ccSVictor Chong 		if (err) {
2842de0c5ccSVictor Chong 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
2852de0c5ccSVictor Chong 		}
2862de0c5ccSVictor Chong 		break;
2872de0c5ccSVictor Chong #endif
2882de0c5ccSVictor Chong 	}
2892de0c5ccSVictor Chong 
2902de0c5ccSVictor Chong 	return err;
2912de0c5ccSVictor Chong }
2922de0c5ccSVictor Chong 
2932de0c5ccSVictor Chong /*******************************************************************************
2942de0c5ccSVictor Chong  * This function can be used by the platforms to update/use image
2952de0c5ccSVictor Chong  * information for given `image_id`.
2962de0c5ccSVictor Chong  ******************************************************************************/
2972de0c5ccSVictor Chong int bl2_plat_handle_post_image_load(unsigned int image_id)
2982de0c5ccSVictor Chong {
2992de0c5ccSVictor Chong 	return hikey960_bl2_handle_post_image_load(image_id);
3002de0c5ccSVictor Chong }
3012de0c5ccSVictor Chong 
3022de0c5ccSVictor Chong #else /* LOAD_IMAGE_V2 */
3032de0c5ccSVictor Chong 
3047cb09cb4SHaojian Zhuang struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
3057cb09cb4SHaojian Zhuang {
3062de0c5ccSVictor Chong #if DEBUG
3072de0c5ccSVictor Chong 	bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL;
3082de0c5ccSVictor Chong #endif
3092de0c5ccSVictor Chong 
3107cb09cb4SHaojian Zhuang 	return &bl31_params_mem.bl31_ep_info;
3117cb09cb4SHaojian Zhuang }
3127cb09cb4SHaojian Zhuang 
3137cb09cb4SHaojian Zhuang void bl2_plat_set_bl31_ep_info(image_info_t *image,
3147cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl31_ep_info)
3157cb09cb4SHaojian Zhuang {
3167cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
3177cb09cb4SHaojian Zhuang 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
3187cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
3197cb09cb4SHaojian Zhuang }
3207cb09cb4SHaojian Zhuang 
3215e3325e7SVictor Chong /*******************************************************************************
3225e3325e7SVictor Chong  * Before calling this function BL32 is loaded in memory and its entrypoint
3235e3325e7SVictor Chong  * is set by load_image. This is a placeholder for the platform to change
3245e3325e7SVictor Chong  * the entrypoint of BL32 and set SPSR and security state.
3255e3325e7SVictor Chong  * On Hikey we only set the security state of the entrypoint
3265e3325e7SVictor Chong  ******************************************************************************/
3275e3325e7SVictor Chong #ifdef BL32_BASE
3285e3325e7SVictor Chong void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
3295e3325e7SVictor Chong 					entry_point_info_t *bl32_ep_info)
3305e3325e7SVictor Chong {
3315e3325e7SVictor Chong 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
3325e3325e7SVictor Chong 	/*
3335e3325e7SVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
3345e3325e7SVictor Chong 	 * setting the SPSR prior to entry into the BL32 image.
3355e3325e7SVictor Chong 	 */
3365e3325e7SVictor Chong 	bl32_ep_info->spsr = 0;
3375e3325e7SVictor Chong }
3385e3325e7SVictor Chong 
3395e3325e7SVictor Chong /*******************************************************************************
3405e3325e7SVictor Chong  * Populate the extents of memory available for loading BL32
3415e3325e7SVictor Chong  ******************************************************************************/
3425e3325e7SVictor Chong void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
3435e3325e7SVictor Chong {
3445e3325e7SVictor Chong 	/*
3455e3325e7SVictor Chong 	 * Populate the extents of memory available for loading BL32.
3465e3325e7SVictor Chong 	 */
3475e3325e7SVictor Chong 	bl32_meminfo->total_base = BL32_BASE;
3485e3325e7SVictor Chong 	bl32_meminfo->free_base = BL32_BASE;
3495e3325e7SVictor Chong 	bl32_meminfo->total_size =
3505e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
3515e3325e7SVictor Chong 	bl32_meminfo->free_size =
3525e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
3535e3325e7SVictor Chong }
3545e3325e7SVictor Chong #endif /* BL32_BASE */
3555e3325e7SVictor Chong 
3567cb09cb4SHaojian Zhuang void bl2_plat_set_bl33_ep_info(image_info_t *image,
3577cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl33_ep_info)
3587cb09cb4SHaojian Zhuang {
3597cb09cb4SHaojian Zhuang 	unsigned long el_status;
3607cb09cb4SHaojian Zhuang 	unsigned int mode;
3617cb09cb4SHaojian Zhuang 
3627cb09cb4SHaojian Zhuang 	/* Figure out what mode we enter the non-secure world in */
3637cb09cb4SHaojian Zhuang 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
3647cb09cb4SHaojian Zhuang 	el_status &= ID_AA64PFR0_ELX_MASK;
3657cb09cb4SHaojian Zhuang 
3667cb09cb4SHaojian Zhuang 	if (el_status)
3677cb09cb4SHaojian Zhuang 		mode = MODE_EL2;
3687cb09cb4SHaojian Zhuang 	else
3697cb09cb4SHaojian Zhuang 		mode = MODE_EL1;
3707cb09cb4SHaojian Zhuang 
3717cb09cb4SHaojian Zhuang 	/*
3727cb09cb4SHaojian Zhuang 	 * TODO: Consider the possibility of specifying the SPSR in
3737cb09cb4SHaojian Zhuang 	 * the FIP ToC and allowing the platform to have a say as
3747cb09cb4SHaojian Zhuang 	 * well.
3757cb09cb4SHaojian Zhuang 	 */
3767cb09cb4SHaojian Zhuang 	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
3777cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
3787cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
3797cb09cb4SHaojian Zhuang }
3807cb09cb4SHaojian Zhuang 
3817cb09cb4SHaojian Zhuang void bl2_plat_flush_bl31_params(void)
3827cb09cb4SHaojian Zhuang {
3837cb09cb4SHaojian Zhuang 	flush_dcache_range((unsigned long)&bl31_params_mem,
3847cb09cb4SHaojian Zhuang 			   sizeof(bl2_to_bl31_params_mem_t));
3857cb09cb4SHaojian Zhuang }
3867cb09cb4SHaojian Zhuang 
3877cb09cb4SHaojian Zhuang void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
3887cb09cb4SHaojian Zhuang {
3897cb09cb4SHaojian Zhuang 	bl33_meminfo->total_base = DDR_BASE;
3907cb09cb4SHaojian Zhuang 	bl33_meminfo->total_size = DDR_SIZE;
3917cb09cb4SHaojian Zhuang 	bl33_meminfo->free_base = DDR_BASE;
3927cb09cb4SHaojian Zhuang 	bl33_meminfo->free_size = DDR_SIZE;
3937cb09cb4SHaojian Zhuang }
3942de0c5ccSVictor Chong #endif /* LOAD_IMAGE_V2 */
3957cb09cb4SHaojian Zhuang 
3967cb09cb4SHaojian Zhuang void bl2_early_platform_setup(meminfo_t *mem_layout)
3977cb09cb4SHaojian Zhuang {
3987cb09cb4SHaojian Zhuang 	unsigned int id, uart_base;
3997cb09cb4SHaojian Zhuang 
4007cb09cb4SHaojian Zhuang 	generic_delay_timer_init();
4017cb09cb4SHaojian Zhuang 	hikey960_read_boardid(&id);
4027cb09cb4SHaojian Zhuang 	if (id == 5300)
4037cb09cb4SHaojian Zhuang 		uart_base = PL011_UART5_BASE;
4047cb09cb4SHaojian Zhuang 	else
4057cb09cb4SHaojian Zhuang 		uart_base = PL011_UART6_BASE;
4067cb09cb4SHaojian Zhuang 
4077cb09cb4SHaojian Zhuang 	/* Initialize the console to provide early debug support */
4087cb09cb4SHaojian Zhuang 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
4097cb09cb4SHaojian Zhuang 
4107cb09cb4SHaojian Zhuang 	/* Setup the BL2 memory layout */
4117cb09cb4SHaojian Zhuang 	bl2_tzram_layout = *mem_layout;
4127cb09cb4SHaojian Zhuang }
4137cb09cb4SHaojian Zhuang 
4147cb09cb4SHaojian Zhuang void bl2_plat_arch_setup(void)
4157cb09cb4SHaojian Zhuang {
4167cb09cb4SHaojian Zhuang 	hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
4177cb09cb4SHaojian Zhuang 			      bl2_tzram_layout.total_size,
4187cb09cb4SHaojian Zhuang 			      BL2_RO_BASE,
4197cb09cb4SHaojian Zhuang 			      BL2_RO_LIMIT,
4207cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_BASE,
4217cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_LIMIT);
4227cb09cb4SHaojian Zhuang }
4237cb09cb4SHaojian Zhuang 
4247cb09cb4SHaojian Zhuang void bl2_platform_setup(void)
4257cb09cb4SHaojian Zhuang {
4267cb09cb4SHaojian Zhuang 	/* disable WDT0 */
4277cb09cb4SHaojian Zhuang 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
4287cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
4297cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
4307cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
4317cb09cb4SHaojian Zhuang 	}
4327cb09cb4SHaojian Zhuang }
433