1 /* 2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 #include <string.h> 10 11 #include <arch_helpers.h> 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <common/desc_image_load.h> 15 #include <drivers/arm/pl011.h> 16 #include <drivers/generic_delay_timer.h> 17 #include <drivers/partition/partition.h> 18 #include <drivers/synopsys/dw_mmc.h> 19 #include <drivers/mmc.h> 20 #include <lib/mmio.h> 21 #include <lib/optee_utils.h> 22 #include <plat/common/platform.h> 23 24 #include "hi3798cv200.h" 25 #include "plat_private.h" 26 27 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 28 static console_t console; 29 30 /******************************************************************************* 31 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. 32 * Return 0 on success, -1 otherwise. 33 ******************************************************************************/ 34 int plat_poplar_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info) 35 { 36 /* 37 * This platform has no SCP_BL2 yet 38 */ 39 return 0; 40 } 41 42 /******************************************************************************* 43 * Gets SPSR for BL32 entry 44 ******************************************************************************/ 45 uint32_t poplar_get_spsr_for_bl32_entry(void) 46 { 47 /* 48 * The Secure Payload Dispatcher service is responsible for 49 * setting the SPSR prior to entry into the BL3-2 image. 50 */ 51 return 0; 52 } 53 54 /******************************************************************************* 55 * Gets SPSR for BL33 entry 56 ******************************************************************************/ 57 #ifdef __aarch64__ 58 uint32_t poplar_get_spsr_for_bl33_entry(void) 59 { 60 unsigned long el_status; 61 unsigned int mode; 62 uint32_t spsr; 63 64 /* Figure out what mode we enter the non-secure world in */ 65 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; 66 el_status &= ID_AA64PFR0_ELX_MASK; 67 68 mode = (el_status) ? MODE_EL2 : MODE_EL1; 69 70 /* 71 * TODO: Consider the possibility of specifying the SPSR in 72 * the FIP ToC and allowing the platform to have a say as 73 * well. 74 */ 75 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 76 return spsr; 77 } 78 #else 79 uint32_t poplar_get_spsr_for_bl33_entry(void) 80 { 81 unsigned int hyp_status, mode, spsr; 82 83 hyp_status = GET_VIRT_EXT(read_id_pfr1()); 84 85 mode = (hyp_status) ? MODE32_hyp : MODE32_svc; 86 87 /* 88 * TODO: Consider the possibility of specifying the SPSR in 89 * the FIP ToC and allowing the platform to have a say as 90 * well. 91 */ 92 spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1, 93 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 94 return spsr; 95 } 96 #endif /* __aarch64__ */ 97 98 int poplar_bl2_handle_post_image_load(unsigned int image_id) 99 { 100 int err = 0; 101 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 102 #ifdef SPD_opteed 103 bl_mem_params_node_t *pager_mem_params = NULL; 104 bl_mem_params_node_t *paged_mem_params = NULL; 105 #endif 106 107 assert(bl_mem_params); 108 109 switch (image_id) { 110 #ifdef __aarch64__ 111 case BL32_IMAGE_ID: 112 #ifdef SPD_opteed 113 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); 114 assert(pager_mem_params); 115 116 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); 117 assert(paged_mem_params); 118 119 err = parse_optee_header(&bl_mem_params->ep_info, 120 &pager_mem_params->image_info, 121 &paged_mem_params->image_info); 122 if (err != 0) { 123 WARN("OPTEE header parse error.\n"); 124 } 125 126 /* 127 * OP-TEE expect to receive DTB address in x2. 128 * This will be copied into x2 by dispatcher. 129 * Set this (arg3) if necessary 130 */ 131 /* bl_mem_params->ep_info.args.arg3 = PLAT_HIKEY_DT_BASE; */ 132 #endif 133 bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl32_entry(); 134 break; 135 #endif 136 137 case BL33_IMAGE_ID: 138 /* BL33 expects to receive the primary CPU MPID (through r0) */ 139 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 140 bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl33_entry(); 141 break; 142 143 #ifdef SCP_BL2_BASE 144 case SCP_BL2_IMAGE_ID: 145 /* The subsequent handling of SCP_BL2 is platform specific */ 146 err = plat_poplar_bl2_handle_scp_bl2(&bl_mem_params->image_info); 147 if (err) { 148 WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); 149 } 150 break; 151 #endif 152 default: 153 /* Do nothing in default case */ 154 break; 155 } 156 157 return err; 158 } 159 160 /******************************************************************************* 161 * This function can be used by the platforms to update/use image 162 * information for given `image_id`. 163 ******************************************************************************/ 164 int bl2_plat_handle_post_image_load(unsigned int image_id) 165 { 166 return poplar_bl2_handle_post_image_load(image_id); 167 } 168 169 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, 170 u_register_t arg2, u_register_t arg3) 171 { 172 struct meminfo *mem_layout = (struct meminfo *)arg1; 173 #if !POPLAR_RECOVERY 174 struct mmc_device_info info; 175 176 dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE); 177 #endif 178 179 console_pl011_register(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, 180 PL011_BAUDRATE, &console); 181 182 /* Enable arch timer */ 183 generic_delay_timer_init(); 184 185 bl2_tzram_layout = *mem_layout; 186 187 #if !POPLAR_RECOVERY 188 /* SoC-specific emmc register are initialized/configured by bootrom */ 189 INFO("BL2: initializing emmc\n"); 190 info.mmc_dev_type = MMC_IS_EMMC; 191 dw_mmc_init(¶ms, &info); 192 #endif 193 194 plat_io_setup(); 195 } 196 197 void bl2_plat_arch_setup(void) 198 { 199 plat_configure_mmu_el1(bl2_tzram_layout.total_base, 200 bl2_tzram_layout.total_size, 201 BL_CODE_BASE, 202 BL_CODE_END, 203 BL_COHERENT_RAM_BASE, 204 BL_COHERENT_RAM_END); 205 } 206 207 void bl2_platform_setup(void) 208 { 209 } 210 211 uintptr_t plat_get_ns_image_entrypoint(void) 212 { 213 #ifdef PRELOADED_BL33_BASE 214 return PRELOADED_BL33_BASE; 215 #else 216 return PLAT_POPLAR_NS_IMAGE_OFFSET; 217 #endif 218 } 219