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