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 <errno.h> 13 #include <generic_delay_timer.h> 14 #include <mmio.h> 15 #include <partition/partition.h> 16 #include <platform.h> 17 #include <string.h> 18 #include "hi3798cv200.h" 19 #include "plat_private.h" 20 21 /* Memory ranges for code and read only data sections */ 22 #define BL2_RO_BASE (unsigned long)(&__RO_START__) 23 #define BL2_RO_LIMIT (unsigned long)(&__RO_END__) 24 25 /* Memory ranges for coherent memory section */ 26 #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) 27 #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) 28 29 typedef struct bl2_to_bl31_params_mem { 30 bl31_params_t bl31_params; 31 image_info_t bl31_image_info; 32 image_info_t bl32_image_info; 33 image_info_t bl33_image_info; 34 entry_point_info_t bl33_ep_info; 35 entry_point_info_t bl32_ep_info; 36 entry_point_info_t bl31_ep_info; 37 } bl2_to_bl31_params_mem_t; 38 39 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 40 static bl2_to_bl31_params_mem_t bl31_params_mem; 41 42 meminfo_t *bl2_plat_sec_mem_layout(void) 43 { 44 return &bl2_tzram_layout; 45 } 46 47 bl31_params_t *bl2_plat_get_bl31_params(void) 48 { 49 bl31_params_t *bl2_to_bl31_params = NULL; 50 51 /* 52 * Initialise the memory for all the arguments that needs to 53 * be passed to BL3-1 54 */ 55 memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t)); 56 57 /* Assign memory for TF related information */ 58 bl2_to_bl31_params = &bl31_params_mem.bl31_params; 59 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); 60 61 /* Fill BL3-1 related information */ 62 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; 63 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, 64 PARAM_IMAGE_BINARY, VERSION_1, 0); 65 66 /* Fill BL3-2 related information if it exists */ 67 #ifdef BL32_BASE 68 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; 69 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, 70 VERSION_1, 0); 71 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; 72 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, 73 VERSION_1, 0); 74 #endif 75 76 /* Fill BL3-3 related information */ 77 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; 78 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, 79 PARAM_EP, VERSION_1, 0); 80 81 /* BL3-3 expects to receive the primary CPU MPID (through x0) */ 82 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr(); 83 84 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; 85 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, 86 PARAM_IMAGE_BINARY, VERSION_1, 0); 87 88 return bl2_to_bl31_params; 89 } 90 91 struct entry_point_info *bl2_plat_get_bl31_ep_info(void) 92 { 93 return &bl31_params_mem.bl31_ep_info; 94 } 95 96 void bl2_plat_set_bl31_ep_info(image_info_t *image, 97 entry_point_info_t *bl31_ep_info) 98 { 99 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); 100 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, 101 DISABLE_ALL_EXCEPTIONS); 102 } 103 104 /******************************************************************************* 105 * Before calling this function BL32 is loaded in memory and its entrypoint 106 * is set by load_image. This is a placeholder for the platform to change 107 * the entrypoint of BL32 and set SPSR and security state. 108 * On Poplar we only set the security state of the entrypoint 109 ******************************************************************************/ 110 #ifdef BL32_BASE 111 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, 112 entry_point_info_t *bl32_ep_info) 113 { 114 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); 115 /* 116 * The Secure Payload Dispatcher service is responsible for 117 * setting the SPSR prior to entry into the BL32 image. 118 */ 119 bl32_ep_info->spsr = 0; 120 } 121 122 /******************************************************************************* 123 * Populate the extents of memory available for loading BL32 124 ******************************************************************************/ 125 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) 126 { 127 /* 128 * Populate the extents of memory available for loading BL32. 129 */ 130 bl32_meminfo->total_base = BL32_BASE; 131 bl32_meminfo->free_base = BL32_BASE; 132 bl32_meminfo->total_size = 133 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; 134 bl32_meminfo->free_size = 135 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; 136 } 137 #endif /* BL32_BASE */ 138 139 static uint32_t hisi_get_spsr_for_bl33_entry(void) 140 { 141 unsigned long el_status; 142 unsigned int mode; 143 uint32_t spsr; 144 145 /* Figure out what mode we enter the non-secure world in */ 146 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; 147 el_status &= ID_AA64PFR0_ELX_MASK; 148 149 mode = (el_status) ? MODE_EL2 : MODE_EL1; 150 151 /* 152 * TODO: Consider the possibility of specifying the SPSR in 153 * the FIP ToC and allowing the platform to have a say as 154 * well. 155 */ 156 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 157 return spsr; 158 } 159 160 void bl2_plat_set_bl33_ep_info(image_info_t *image, 161 entry_point_info_t *bl33_ep_info) 162 { 163 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); 164 bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry(); 165 bl33_ep_info->args.arg2 = image->image_size; 166 } 167 168 void bl2_plat_flush_bl31_params(void) 169 { 170 flush_dcache_range((unsigned long)&bl31_params_mem, 171 sizeof(bl2_to_bl31_params_mem_t)); 172 } 173 174 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) 175 { 176 bl33_meminfo->total_base = DDR_BASE; 177 bl33_meminfo->total_size = DDR_SIZE; 178 bl33_meminfo->free_base = DDR_BASE; 179 bl33_meminfo->free_size = DDR_SIZE; 180 } 181 182 void bl2_early_platform_setup(meminfo_t *mem_layout) 183 { 184 console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE); 185 186 /* Enable arch timer */ 187 generic_delay_timer_init(); 188 189 bl2_tzram_layout = *mem_layout; 190 } 191 192 void bl2_plat_arch_setup(void) 193 { 194 plat_configure_mmu_el1(bl2_tzram_layout.total_base, 195 bl2_tzram_layout.total_size, 196 BL2_RO_BASE, 197 BL2_RO_LIMIT, 198 BL2_COHERENT_RAM_BASE, 199 BL2_COHERENT_RAM_LIMIT); 200 } 201 202 void bl2_platform_setup(void) 203 { 204 plat_io_setup(); 205 } 206 207 unsigned long plat_get_ns_image_entrypoint(void) 208 { 209 return PLAT_POPLAR_NS_IMAGE_OFFSET; 210 } 211