Home | History | Annotate | Download | only in hikey960
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <arch_helpers.h>
      8 #include <assert.h>
      9 #include <bl_common.h>
     10 #include <console.h>
     11 #include <debug.h>
     12 #include <desc_image_load.h>
     13 #include <errno.h>
     14 #include <generic_delay_timer.h>
     15 #include <hi3660.h>
     16 #include <mmio.h>
     17 #if LOAD_IMAGE_V2
     18 #ifdef SPD_opteed
     19 #include <optee_utils.h>
     20 #endif
     21 #endif
     22 #include <platform_def.h>
     23 #include <string.h>
     24 #include <ufs.h>
     25 
     26 #include "hikey960_def.h"
     27 #include "hikey960_private.h"
     28 
     29 /*
     30  * The next 2 constants identify the extents of the code & RO data region.
     31  * These addresses are used by the MMU setup code and therefore they must be
     32  * page-aligned.  It is the responsibility of the linker script to ensure that
     33  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
     34  */
     35 #define BL2_RO_BASE (unsigned long)(&__RO_START__)
     36 #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
     37 
     38 /*
     39  * The next 2 constants identify the extents of the coherent memory region.
     40  * These addresses are used by the MMU setup code and therefore they must be
     41  * page-aligned.  It is the responsibility of the linker script to ensure that
     42  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
     43  * page-aligned addresses.
     44  */
     45 #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
     46 #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
     47 
     48 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
     49 
     50 #if !LOAD_IMAGE_V2
     51 
     52 /*******************************************************************************
     53  * This structure represents the superset of information that is passed to
     54  * BL31, e.g. while passing control to it from BL2, bl31_params
     55  * and other platform specific params
     56  ******************************************************************************/
     57 typedef struct bl2_to_bl31_params_mem {
     58 	bl31_params_t		bl31_params;
     59 	image_info_t		bl31_image_info;
     60 	image_info_t		bl32_image_info;
     61 	image_info_t		bl33_image_info;
     62 	entry_point_info_t	bl33_ep_info;
     63 	entry_point_info_t	bl32_ep_info;
     64 	entry_point_info_t	bl31_ep_info;
     65 } bl2_to_bl31_params_mem_t;
     66 
     67 static bl2_to_bl31_params_mem_t bl31_params_mem;
     68 
     69 meminfo_t *bl2_plat_sec_mem_layout(void)
     70 {
     71 	return &bl2_tzram_layout;
     72 }
     73 
     74 bl31_params_t *bl2_plat_get_bl31_params(void)
     75 {
     76 	bl31_params_t *bl2_to_bl31_params = NULL;
     77 
     78 	/*
     79 	 * Initialise the memory for all the arguments that needs to
     80 	 * be passed to BL3-1
     81 	 */
     82 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
     83 
     84 	/* Assign memory for TF related information */
     85 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
     86 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
     87 
     88 	/* Fill BL3-1 related information */
     89 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
     90 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
     91 		VERSION_1, 0);
     92 
     93 	/* Fill BL3-2 related information if it exists */
     94 #ifdef BL32_BASE
     95 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
     96 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
     97 		VERSION_1, 0);
     98 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
     99 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
    100 		VERSION_1, 0);
    101 #endif
    102 
    103 	/* Fill BL3-3 related information */
    104 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
    105 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
    106 		PARAM_EP, VERSION_1, 0);
    107 
    108 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
    109 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
    110 
    111 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
    112 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
    113 		VERSION_1, 0);
    114 
    115 	return bl2_to_bl31_params;
    116 }
    117 
    118 /*******************************************************************************
    119  * Populate the extents of memory available for loading SCP_BL2 (if used),
    120  * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
    121  ******************************************************************************/
    122 void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
    123 {
    124 	hikey960_init_ufs();
    125 	hikey960_io_setup();
    126 
    127 	*scp_bl2_meminfo = bl2_tzram_layout;
    128 }
    129 #endif /* LOAD_IMAGE_V2 */
    130 
    131 extern int load_lpm3(void);
    132 
    133 /*******************************************************************************
    134  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
    135  * Return 0 on success, -1 otherwise.
    136  ******************************************************************************/
    137 #if LOAD_IMAGE_V2
    138 int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
    139 #else
    140 int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
    141 #endif
    142 {
    143 	int i;
    144 	int *buf;
    145 
    146 	assert(scp_bl2_image_info->image_size < SCP_BL2_SIZE);
    147 
    148 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
    149 
    150 	INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
    151 	     scp_bl2_image_info->image_base,
    152 	     scp_bl2_image_info->image_size);
    153 
    154 	buf = (int *)scp_bl2_image_info->image_base;
    155 
    156 	INFO("BL2: SCP_BL2 HEAD:\n");
    157 	for (i = 0; i < 64; i += 4)
    158 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
    159 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
    160 
    161 	buf = (int *)(scp_bl2_image_info->image_base +
    162 		      scp_bl2_image_info->image_size - 256);
    163 
    164 	INFO("BL2: SCP_BL2 TAIL:\n");
    165 	for (i = 0; i < 64; i += 4)
    166 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
    167 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
    168 
    169 	INFO("BL2: SCP_BL2 transferred to SCP\n");
    170 
    171 	load_lpm3();
    172 	(void)buf;
    173 
    174 	return 0;
    175 }
    176 
    177 void hikey960_init_ufs(void)
    178 {
    179 	ufs_params_t ufs_params;
    180 
    181 	memset(&ufs_params, 0, sizeof(ufs_params_t));
    182 	ufs_params.reg_base = UFS_REG_BASE;
    183 	ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
    184 	ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
    185 	ufs_params.flags = UFS_FLAGS_SKIPINIT;
    186 	ufs_init(NULL, &ufs_params);
    187 }
    188 
    189 /*******************************************************************************
    190  * Gets SPSR for BL32 entry
    191  ******************************************************************************/
    192 uint32_t hikey960_get_spsr_for_bl32_entry(void)
    193 {
    194 	/*
    195 	 * The Secure Payload Dispatcher service is responsible for
    196 	 * setting the SPSR prior to entry into the BL3-2 image.
    197 	 */
    198 	return 0;
    199 }
    200 
    201 /*******************************************************************************
    202  * Gets SPSR for BL33 entry
    203  ******************************************************************************/
    204 #ifndef AARCH32
    205 uint32_t hikey960_get_spsr_for_bl33_entry(void)
    206 {
    207 	unsigned int mode;
    208 	uint32_t spsr;
    209 
    210 	/* Figure out what mode we enter the non-secure world in */
    211 	mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
    212 
    213 	/*
    214 	 * TODO: Consider the possibility of specifying the SPSR in
    215 	 * the FIP ToC and allowing the platform to have a say as
    216 	 * well.
    217 	 */
    218 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
    219 	return spsr;
    220 }
    221 #else
    222 uint32_t hikey960_get_spsr_for_bl33_entry(void)
    223 {
    224 	unsigned int hyp_status, mode, spsr;
    225 
    226 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
    227 
    228 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
    229 
    230 	/*
    231 	 * TODO: Consider the possibility of specifying the SPSR in
    232 	 * the FIP ToC and allowing the platform to have a say as
    233 	 * well.
    234 	 */
    235 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
    236 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
    237 	return spsr;
    238 }
    239 #endif /* AARCH32 */
    240 
    241 #if LOAD_IMAGE_V2
    242 int hikey960_bl2_handle_post_image_load(unsigned int image_id)
    243 {
    244 	int err = 0;
    245 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
    246 #ifdef SPD_opteed
    247 	bl_mem_params_node_t *pager_mem_params = NULL;
    248 	bl_mem_params_node_t *paged_mem_params = NULL;
    249 #endif
    250 	assert(bl_mem_params);
    251 
    252 	switch (image_id) {
    253 #ifdef AARCH64
    254 	case BL32_IMAGE_ID:
    255 #ifdef SPD_opteed
    256 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
    257 		assert(pager_mem_params);
    258 
    259 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
    260 		assert(paged_mem_params);
    261 
    262 		err = parse_optee_header(&bl_mem_params->ep_info,
    263 				&pager_mem_params->image_info,
    264 				&paged_mem_params->image_info);
    265 		if (err != 0) {
    266 			WARN("OPTEE header parse error.\n");
    267 		}
    268 #endif
    269 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl32_entry();
    270 		break;
    271 #endif
    272 
    273 	case BL33_IMAGE_ID:
    274 		/* BL33 expects to receive the primary CPU MPID (through r0) */
    275 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
    276 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl33_entry();
    277 		break;
    278 
    279 #ifdef SCP_BL2_BASE
    280 	case SCP_BL2_IMAGE_ID:
    281 		/* The subsequent handling of SCP_BL2 is platform specific */
    282 		err = plat_hikey960_bl2_handle_scp_bl2(&bl_mem_params->image_info);
    283 		if (err) {
    284 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
    285 		}
    286 		break;
    287 #endif
    288 	}
    289 
    290 	return err;
    291 }
    292 
    293 /*******************************************************************************
    294  * This function can be used by the platforms to update/use image
    295  * information for given `image_id`.
    296  ******************************************************************************/
    297 int bl2_plat_handle_post_image_load(unsigned int image_id)
    298 {
    299 	return hikey960_bl2_handle_post_image_load(image_id);
    300 }
    301 
    302 #else /* LOAD_IMAGE_V2 */
    303 
    304 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
    305 {
    306 #if DEBUG
    307 	bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL;
    308 #endif
    309 
    310 	return &bl31_params_mem.bl31_ep_info;
    311 }
    312 
    313 void bl2_plat_set_bl31_ep_info(image_info_t *image,
    314 			       entry_point_info_t *bl31_ep_info)
    315 {
    316 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
    317 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
    318 				       DISABLE_ALL_EXCEPTIONS);
    319 }
    320 
    321 /*******************************************************************************
    322  * Before calling this function BL32 is loaded in memory and its entrypoint
    323  * is set by load_image. This is a placeholder for the platform to change
    324  * the entrypoint of BL32 and set SPSR and security state.
    325  * On Hikey we only set the security state of the entrypoint
    326  ******************************************************************************/
    327 #ifdef BL32_BASE
    328 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
    329 					entry_point_info_t *bl32_ep_info)
    330 {
    331 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
    332 	/*
    333 	 * The Secure Payload Dispatcher service is responsible for
    334 	 * setting the SPSR prior to entry into the BL32 image.
    335 	 */
    336 	bl32_ep_info->spsr = 0;
    337 }
    338 
    339 /*******************************************************************************
    340  * Populate the extents of memory available for loading BL32
    341  ******************************************************************************/
    342 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
    343 {
    344 	/*
    345 	 * Populate the extents of memory available for loading BL32.
    346 	 */
    347 	bl32_meminfo->total_base = BL32_BASE;
    348 	bl32_meminfo->free_base = BL32_BASE;
    349 	bl32_meminfo->total_size =
    350 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
    351 	bl32_meminfo->free_size =
    352 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
    353 }
    354 #endif /* BL32_BASE */
    355 
    356 void bl2_plat_set_bl33_ep_info(image_info_t *image,
    357 			       entry_point_info_t *bl33_ep_info)
    358 {
    359 	unsigned long el_status;
    360 	unsigned int mode;
    361 
    362 	/* Figure out what mode we enter the non-secure world in */
    363 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
    364 	el_status &= ID_AA64PFR0_ELX_MASK;
    365 
    366 	if (el_status)
    367 		mode = MODE_EL2;
    368 	else
    369 		mode = MODE_EL1;
    370 
    371 	/*
    372 	 * TODO: Consider the possibility of specifying the SPSR in
    373 	 * the FIP ToC and allowing the platform to have a say as
    374 	 * well.
    375 	 */
    376 	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
    377 				       DISABLE_ALL_EXCEPTIONS);
    378 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
    379 }
    380 
    381 void bl2_plat_flush_bl31_params(void)
    382 {
    383 	flush_dcache_range((unsigned long)&bl31_params_mem,
    384 			   sizeof(bl2_to_bl31_params_mem_t));
    385 }
    386 
    387 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
    388 {
    389 	bl33_meminfo->total_base = DDR_BASE;
    390 	bl33_meminfo->total_size = DDR_SIZE;
    391 	bl33_meminfo->free_base = DDR_BASE;
    392 	bl33_meminfo->free_size = DDR_SIZE;
    393 }
    394 #endif /* LOAD_IMAGE_V2 */
    395 
    396 void bl2_early_platform_setup(meminfo_t *mem_layout)
    397 {
    398 	unsigned int id, uart_base;
    399 
    400 	generic_delay_timer_init();
    401 	hikey960_read_boardid(&id);
    402 	if (id == 5300)
    403 		uart_base = PL011_UART5_BASE;
    404 	else
    405 		uart_base = PL011_UART6_BASE;
    406 
    407 	/* Initialize the console to provide early debug support */
    408 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
    409 
    410 	/* Setup the BL2 memory layout */
    411 	bl2_tzram_layout = *mem_layout;
    412 }
    413 
    414 void bl2_plat_arch_setup(void)
    415 {
    416 	hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
    417 			      bl2_tzram_layout.total_size,
    418 			      BL2_RO_BASE,
    419 			      BL2_RO_LIMIT,
    420 			      BL2_COHERENT_RAM_BASE,
    421 			      BL2_COHERENT_RAM_LIMIT);
    422 }
    423 
    424 void bl2_platform_setup(void)
    425 {
    426 	/* disable WDT0 */
    427 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
    428 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
    429 		mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
    430 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
    431 	}
    432 }
    433