xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_bl2_setup.c (revision 5e3325e73c0aca2934982cb10b881064d9b657f1)
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>
127cb09cb4SHaojian Zhuang #include <errno.h>
137cb09cb4SHaojian Zhuang #include <generic_delay_timer.h>
147cb09cb4SHaojian Zhuang #include <hi3660.h>
157cb09cb4SHaojian Zhuang #include <mmio.h>
167cb09cb4SHaojian Zhuang #include <platform_def.h>
177cb09cb4SHaojian Zhuang #include <string.h>
187cb09cb4SHaojian Zhuang #include <ufs.h>
197cb09cb4SHaojian Zhuang 
207cb09cb4SHaojian Zhuang #include "hikey960_def.h"
217cb09cb4SHaojian Zhuang #include "hikey960_private.h"
227cb09cb4SHaojian Zhuang 
237cb09cb4SHaojian Zhuang /*
247cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the code & RO data region.
257cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
267cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
277cb09cb4SHaojian Zhuang  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
287cb09cb4SHaojian Zhuang  */
297cb09cb4SHaojian Zhuang #define BL2_RO_BASE (unsigned long)(&__RO_START__)
307cb09cb4SHaojian Zhuang #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
317cb09cb4SHaojian Zhuang 
327cb09cb4SHaojian Zhuang /*
337cb09cb4SHaojian Zhuang  * The next 2 constants identify the extents of the coherent memory region.
347cb09cb4SHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
357cb09cb4SHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
367cb09cb4SHaojian Zhuang  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
377cb09cb4SHaojian Zhuang  * page-aligned addresses.
387cb09cb4SHaojian Zhuang  */
397cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
407cb09cb4SHaojian Zhuang #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
417cb09cb4SHaojian Zhuang 
427cb09cb4SHaojian Zhuang static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
437cb09cb4SHaojian Zhuang 
447cb09cb4SHaojian Zhuang typedef struct bl2_to_bl31_params_mem {
457cb09cb4SHaojian Zhuang 	bl31_params_t		bl31_params;
467cb09cb4SHaojian Zhuang 	image_info_t		bl31_image_info;
477cb09cb4SHaojian Zhuang 	image_info_t		bl32_image_info;
487cb09cb4SHaojian Zhuang 	image_info_t		bl33_image_info;
497cb09cb4SHaojian Zhuang 	entry_point_info_t	bl33_ep_info;
507cb09cb4SHaojian Zhuang 	entry_point_info_t	bl32_ep_info;
517cb09cb4SHaojian Zhuang 	entry_point_info_t	bl31_ep_info;
527cb09cb4SHaojian Zhuang } bl2_to_bl31_params_mem_t;
537cb09cb4SHaojian Zhuang 
547cb09cb4SHaojian Zhuang static bl2_to_bl31_params_mem_t bl31_params_mem;
557cb09cb4SHaojian Zhuang 
567cb09cb4SHaojian Zhuang meminfo_t *bl2_plat_sec_mem_layout(void)
577cb09cb4SHaojian Zhuang {
587cb09cb4SHaojian Zhuang 	return &bl2_tzram_layout;
597cb09cb4SHaojian Zhuang }
607cb09cb4SHaojian Zhuang 
617cb09cb4SHaojian Zhuang bl31_params_t *bl2_plat_get_bl31_params(void)
627cb09cb4SHaojian Zhuang {
637cb09cb4SHaojian Zhuang 	bl31_params_t *bl2_to_bl31_params = NULL;
647cb09cb4SHaojian Zhuang 
657cb09cb4SHaojian Zhuang 	/*
667cb09cb4SHaojian Zhuang 	 * Initialise the memory for all the arguments that needs to
677cb09cb4SHaojian Zhuang 	 * be passed to BL3-1
687cb09cb4SHaojian Zhuang 	 */
697cb09cb4SHaojian Zhuang 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
707cb09cb4SHaojian Zhuang 
717cb09cb4SHaojian Zhuang 	/* Assign memory for TF related information */
727cb09cb4SHaojian Zhuang 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
737cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
747cb09cb4SHaojian Zhuang 
757cb09cb4SHaojian Zhuang 	/* Fill BL3-1 related information */
767cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
777cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
787cb09cb4SHaojian Zhuang 		VERSION_1, 0);
797cb09cb4SHaojian Zhuang 
807cb09cb4SHaojian Zhuang 	/* Fill BL3-2 related information if it exists */
817cb09cb4SHaojian Zhuang #if BL32_BASE
827cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
837cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
847cb09cb4SHaojian Zhuang 		VERSION_1, 0);
857cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
867cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
877cb09cb4SHaojian Zhuang 		VERSION_1, 0);
887cb09cb4SHaojian Zhuang #endif
897cb09cb4SHaojian Zhuang 
907cb09cb4SHaojian Zhuang 	/* Fill BL3-3 related information */
917cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
927cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
937cb09cb4SHaojian Zhuang 		PARAM_EP, VERSION_1, 0);
947cb09cb4SHaojian Zhuang 
957cb09cb4SHaojian Zhuang 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
967cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
977cb09cb4SHaojian Zhuang 
987cb09cb4SHaojian Zhuang 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
997cb09cb4SHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
1007cb09cb4SHaojian Zhuang 		VERSION_1, 0);
1017cb09cb4SHaojian Zhuang 
1027cb09cb4SHaojian Zhuang 	return bl2_to_bl31_params;
1037cb09cb4SHaojian Zhuang }
1047cb09cb4SHaojian Zhuang 
1057cb09cb4SHaojian Zhuang /*******************************************************************************
1067cb09cb4SHaojian Zhuang  * Populate the extents of memory available for loading SCP_BL2 (if used),
1077cb09cb4SHaojian Zhuang  * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
1087cb09cb4SHaojian Zhuang  ******************************************************************************/
1097cb09cb4SHaojian Zhuang void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
1107cb09cb4SHaojian Zhuang {
1117cb09cb4SHaojian Zhuang 	ufs_params_t ufs_params;
1127cb09cb4SHaojian Zhuang 
1137cb09cb4SHaojian Zhuang 	memset(&ufs_params, 0, sizeof(ufs_params_t));
1147cb09cb4SHaojian Zhuang 	ufs_params.reg_base = UFS_REG_BASE;
1157cb09cb4SHaojian Zhuang 	ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
1167cb09cb4SHaojian Zhuang 	ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
1177cb09cb4SHaojian Zhuang 	ufs_params.flags = UFS_FLAGS_SKIPINIT;
1187cb09cb4SHaojian Zhuang 	ufs_init(NULL, &ufs_params);
1197cb09cb4SHaojian Zhuang 
1207cb09cb4SHaojian Zhuang 	hikey960_io_setup();
1217cb09cb4SHaojian Zhuang 
1227cb09cb4SHaojian Zhuang 	*scp_bl2_meminfo = bl2_tzram_layout;
1237cb09cb4SHaojian Zhuang }
1247cb09cb4SHaojian Zhuang 
1257cb09cb4SHaojian Zhuang extern int load_lpm3(void);
1267cb09cb4SHaojian Zhuang 
1277cb09cb4SHaojian Zhuang int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
1287cb09cb4SHaojian Zhuang {
1297cb09cb4SHaojian Zhuang 	int i;
1307cb09cb4SHaojian Zhuang 	int *buf;
1317cb09cb4SHaojian Zhuang 
1327cb09cb4SHaojian Zhuang 	assert(scp_bl2_image_info->image_size < SCP_MEM_SIZE);
1337cb09cb4SHaojian Zhuang 
1347cb09cb4SHaojian Zhuang 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
1357cb09cb4SHaojian Zhuang 
1367cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
1377cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_base,
1387cb09cb4SHaojian Zhuang 	     scp_bl2_image_info->image_size);
1397cb09cb4SHaojian Zhuang 
1407cb09cb4SHaojian Zhuang 	buf = (int *)scp_bl2_image_info->image_base;
1417cb09cb4SHaojian Zhuang 
1427cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 HEAD:\n");
1437cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1447cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1457cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1467cb09cb4SHaojian Zhuang 
1477cb09cb4SHaojian Zhuang 	buf = (int *)(scp_bl2_image_info->image_base +
1487cb09cb4SHaojian Zhuang 		      scp_bl2_image_info->image_size - 256);
1497cb09cb4SHaojian Zhuang 
1507cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 TAIL:\n");
1517cb09cb4SHaojian Zhuang 	for (i = 0; i < 64; i += 4)
1527cb09cb4SHaojian Zhuang 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
1537cb09cb4SHaojian Zhuang 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
1547cb09cb4SHaojian Zhuang 
1557cb09cb4SHaojian Zhuang 	memcpy((void *)SCP_MEM_BASE,
1567cb09cb4SHaojian Zhuang 	       (void *)scp_bl2_image_info->image_base,
1577cb09cb4SHaojian Zhuang 	       scp_bl2_image_info->image_size);
1587cb09cb4SHaojian Zhuang 
1597cb09cb4SHaojian Zhuang 	INFO("BL2: SCP_BL2 transferred to SCP\n");
1607cb09cb4SHaojian Zhuang 
1617cb09cb4SHaojian Zhuang 	load_lpm3();
1627cb09cb4SHaojian Zhuang 	(void)buf;
1637cb09cb4SHaojian Zhuang 
1647cb09cb4SHaojian Zhuang 	return 0;
1657cb09cb4SHaojian Zhuang }
1667cb09cb4SHaojian Zhuang 
1677cb09cb4SHaojian Zhuang struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
1687cb09cb4SHaojian Zhuang {
1697cb09cb4SHaojian Zhuang 	return &bl31_params_mem.bl31_ep_info;
1707cb09cb4SHaojian Zhuang }
1717cb09cb4SHaojian Zhuang 
1727cb09cb4SHaojian Zhuang void bl2_plat_set_bl31_ep_info(image_info_t *image,
1737cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl31_ep_info)
1747cb09cb4SHaojian Zhuang {
1757cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
1767cb09cb4SHaojian Zhuang 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
1777cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
1787cb09cb4SHaojian Zhuang }
1797cb09cb4SHaojian Zhuang 
180*5e3325e7SVictor Chong /*******************************************************************************
181*5e3325e7SVictor Chong  * Before calling this function BL32 is loaded in memory and its entrypoint
182*5e3325e7SVictor Chong  * is set by load_image. This is a placeholder for the platform to change
183*5e3325e7SVictor Chong  * the entrypoint of BL32 and set SPSR and security state.
184*5e3325e7SVictor Chong  * On Hikey we only set the security state of the entrypoint
185*5e3325e7SVictor Chong  ******************************************************************************/
186*5e3325e7SVictor Chong #ifdef BL32_BASE
187*5e3325e7SVictor Chong void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
188*5e3325e7SVictor Chong 					entry_point_info_t *bl32_ep_info)
189*5e3325e7SVictor Chong {
190*5e3325e7SVictor Chong 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
191*5e3325e7SVictor Chong 	/*
192*5e3325e7SVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
193*5e3325e7SVictor Chong 	 * setting the SPSR prior to entry into the BL32 image.
194*5e3325e7SVictor Chong 	 */
195*5e3325e7SVictor Chong 	bl32_ep_info->spsr = 0;
196*5e3325e7SVictor Chong }
197*5e3325e7SVictor Chong 
198*5e3325e7SVictor Chong /*******************************************************************************
199*5e3325e7SVictor Chong  * Populate the extents of memory available for loading BL32
200*5e3325e7SVictor Chong  ******************************************************************************/
201*5e3325e7SVictor Chong void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
202*5e3325e7SVictor Chong {
203*5e3325e7SVictor Chong 	/*
204*5e3325e7SVictor Chong 	 * Populate the extents of memory available for loading BL32.
205*5e3325e7SVictor Chong 	 */
206*5e3325e7SVictor Chong 	bl32_meminfo->total_base = BL32_BASE;
207*5e3325e7SVictor Chong 	bl32_meminfo->free_base = BL32_BASE;
208*5e3325e7SVictor Chong 	bl32_meminfo->total_size =
209*5e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
210*5e3325e7SVictor Chong 	bl32_meminfo->free_size =
211*5e3325e7SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
212*5e3325e7SVictor Chong }
213*5e3325e7SVictor Chong #endif /* BL32_BASE */
214*5e3325e7SVictor Chong 
2157cb09cb4SHaojian Zhuang void bl2_plat_set_bl33_ep_info(image_info_t *image,
2167cb09cb4SHaojian Zhuang 			       entry_point_info_t *bl33_ep_info)
2177cb09cb4SHaojian Zhuang {
2187cb09cb4SHaojian Zhuang 	unsigned long el_status;
2197cb09cb4SHaojian Zhuang 	unsigned int mode;
2207cb09cb4SHaojian Zhuang 
2217cb09cb4SHaojian Zhuang 	/* Figure out what mode we enter the non-secure world in */
2227cb09cb4SHaojian Zhuang 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
2237cb09cb4SHaojian Zhuang 	el_status &= ID_AA64PFR0_ELX_MASK;
2247cb09cb4SHaojian Zhuang 
2257cb09cb4SHaojian Zhuang 	if (el_status)
2267cb09cb4SHaojian Zhuang 		mode = MODE_EL2;
2277cb09cb4SHaojian Zhuang 	else
2287cb09cb4SHaojian Zhuang 		mode = MODE_EL1;
2297cb09cb4SHaojian Zhuang 
2307cb09cb4SHaojian Zhuang 	/*
2317cb09cb4SHaojian Zhuang 	 * TODO: Consider the possibility of specifying the SPSR in
2327cb09cb4SHaojian Zhuang 	 * the FIP ToC and allowing the platform to have a say as
2337cb09cb4SHaojian Zhuang 	 * well.
2347cb09cb4SHaojian Zhuang 	 */
2357cb09cb4SHaojian Zhuang 	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
2367cb09cb4SHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
2377cb09cb4SHaojian Zhuang 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
2387cb09cb4SHaojian Zhuang }
2397cb09cb4SHaojian Zhuang 
2407cb09cb4SHaojian Zhuang void bl2_plat_flush_bl31_params(void)
2417cb09cb4SHaojian Zhuang {
2427cb09cb4SHaojian Zhuang 	flush_dcache_range((unsigned long)&bl31_params_mem,
2437cb09cb4SHaojian Zhuang 			   sizeof(bl2_to_bl31_params_mem_t));
2447cb09cb4SHaojian Zhuang }
2457cb09cb4SHaojian Zhuang 
2467cb09cb4SHaojian Zhuang void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
2477cb09cb4SHaojian Zhuang {
2487cb09cb4SHaojian Zhuang 	bl33_meminfo->total_base = DDR_BASE;
2497cb09cb4SHaojian Zhuang 	bl33_meminfo->total_size = DDR_SIZE;
2507cb09cb4SHaojian Zhuang 	bl33_meminfo->free_base = DDR_BASE;
2517cb09cb4SHaojian Zhuang 	bl33_meminfo->free_size = DDR_SIZE;
2527cb09cb4SHaojian Zhuang }
2537cb09cb4SHaojian Zhuang 
2547cb09cb4SHaojian Zhuang void bl2_early_platform_setup(meminfo_t *mem_layout)
2557cb09cb4SHaojian Zhuang {
2567cb09cb4SHaojian Zhuang 	unsigned int id, uart_base;
2577cb09cb4SHaojian Zhuang 
2587cb09cb4SHaojian Zhuang 	generic_delay_timer_init();
2597cb09cb4SHaojian Zhuang 	hikey960_read_boardid(&id);
2607cb09cb4SHaojian Zhuang 	if (id == 5300)
2617cb09cb4SHaojian Zhuang 		uart_base = PL011_UART5_BASE;
2627cb09cb4SHaojian Zhuang 	else
2637cb09cb4SHaojian Zhuang 		uart_base = PL011_UART6_BASE;
2647cb09cb4SHaojian Zhuang 
2657cb09cb4SHaojian Zhuang 	/* Initialize the console to provide early debug support */
2667cb09cb4SHaojian Zhuang 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
2677cb09cb4SHaojian Zhuang 
2687cb09cb4SHaojian Zhuang 	/* Setup the BL2 memory layout */
2697cb09cb4SHaojian Zhuang 	bl2_tzram_layout = *mem_layout;
2707cb09cb4SHaojian Zhuang }
2717cb09cb4SHaojian Zhuang 
2727cb09cb4SHaojian Zhuang void bl2_plat_arch_setup(void)
2737cb09cb4SHaojian Zhuang {
2747cb09cb4SHaojian Zhuang 	hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
2757cb09cb4SHaojian Zhuang 			      bl2_tzram_layout.total_size,
2767cb09cb4SHaojian Zhuang 			      BL2_RO_BASE,
2777cb09cb4SHaojian Zhuang 			      BL2_RO_LIMIT,
2787cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_BASE,
2797cb09cb4SHaojian Zhuang 			      BL2_COHERENT_RAM_LIMIT);
2807cb09cb4SHaojian Zhuang }
2817cb09cb4SHaojian Zhuang 
2827cb09cb4SHaojian Zhuang void bl2_platform_setup(void)
2837cb09cb4SHaojian Zhuang {
2847cb09cb4SHaojian Zhuang 	/* disable WDT0 */
2857cb09cb4SHaojian Zhuang 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
2867cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
2877cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
2887cb09cb4SHaojian Zhuang 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
2897cb09cb4SHaojian Zhuang 	}
2907cb09cb4SHaojian Zhuang }
291