1 /* 2 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <libfdt.h> 11 12 #include <platform_def.h> 13 14 #include <arch_helpers.h> 15 #include <common/bl_common.h> 16 #include <common/debug.h> 17 #include <common/desc_image_load.h> 18 #include <common/fdt_fixup.h> 19 #include <common/fdt_wrappers.h> 20 #include <lib/optee_utils.h> 21 #include <lib/utils.h> 22 #include <plat/common/platform.h> 23 24 #include "qemu_private.h" 25 26 #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ 27 bl2_tzram_layout.total_base, \ 28 bl2_tzram_layout.total_size, \ 29 MT_MEMORY | MT_RW | MT_SECURE) 30 31 #define MAP_BL2_RO MAP_REGION_FLAT( \ 32 BL_CODE_BASE, \ 33 BL_CODE_END - BL_CODE_BASE, \ 34 MT_CODE | MT_SECURE), \ 35 MAP_REGION_FLAT( \ 36 BL_RO_DATA_BASE, \ 37 BL_RO_DATA_END \ 38 - BL_RO_DATA_BASE, \ 39 MT_RO_DATA | MT_SECURE) 40 41 #if USE_COHERENT_MEM 42 #define MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \ 43 BL_COHERENT_RAM_BASE, \ 44 BL_COHERENT_RAM_END \ 45 - BL_COHERENT_RAM_BASE, \ 46 MT_DEVICE | MT_RW | MT_SECURE) 47 #endif 48 49 /* Data structure which holds the extents of the trusted SRAM for BL2 */ 50 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 51 52 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, 53 u_register_t arg2, u_register_t arg3) 54 { 55 meminfo_t *mem_layout = (void *)arg1; 56 57 /* Initialize the console to provide early debug support */ 58 qemu_console_init(); 59 60 /* Setup the BL2 memory layout */ 61 bl2_tzram_layout = *mem_layout; 62 63 plat_qemu_io_setup(); 64 } 65 66 static void security_setup(void) 67 { 68 /* 69 * This is where a TrustZone address space controller and other 70 * security related peripherals, would be configured. 71 */ 72 } 73 74 static void update_dt(void) 75 { 76 int ret; 77 void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE; 78 79 ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); 80 if (ret < 0) { 81 ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret); 82 return; 83 } 84 85 if (dt_add_psci_node(fdt)) { 86 ERROR("Failed to add PSCI Device Tree node\n"); 87 return; 88 } 89 90 if (dt_add_psci_cpu_enable_methods(fdt)) { 91 ERROR("Failed to add PSCI cpu enable methods in Device Tree\n"); 92 return; 93 } 94 95 ret = fdt_pack(fdt); 96 if (ret < 0) 97 ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret); 98 } 99 100 void bl2_platform_setup(void) 101 { 102 security_setup(); 103 update_dt(); 104 105 /* TODO Initialize timer */ 106 } 107 108 void bl2_plat_arch_setup(void) 109 { 110 const mmap_region_t bl_regions[] = { 111 MAP_BL2_TOTAL, 112 MAP_BL2_RO, 113 #if USE_COHERENT_MEM 114 MAP_BL_COHERENT_RAM, 115 #endif 116 {0} 117 }; 118 119 setup_page_tables(bl_regions, plat_qemu_get_mmap()); 120 121 #ifdef __aarch64__ 122 enable_mmu_el1(0); 123 #else 124 enable_mmu_svc_mon(0); 125 #endif 126 } 127 128 /******************************************************************************* 129 * Gets SPSR for BL32 entry 130 ******************************************************************************/ 131 static uint32_t qemu_get_spsr_for_bl32_entry(void) 132 { 133 #ifdef __aarch64__ 134 /* 135 * The Secure Payload Dispatcher service is responsible for 136 * setting the SPSR prior to entry into the BL3-2 image. 137 */ 138 return 0; 139 #else 140 return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, 141 DISABLE_ALL_EXCEPTIONS); 142 #endif 143 } 144 145 /******************************************************************************* 146 * Gets SPSR for BL33 entry 147 ******************************************************************************/ 148 static uint32_t qemu_get_spsr_for_bl33_entry(void) 149 { 150 uint32_t spsr; 151 #ifdef __aarch64__ 152 unsigned int mode; 153 154 /* Figure out what mode we enter the non-secure world in */ 155 mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; 156 157 /* 158 * TODO: Consider the possibility of specifying the SPSR in 159 * the FIP ToC and allowing the platform to have a say as 160 * well. 161 */ 162 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 163 #else 164 spsr = SPSR_MODE32(MODE32_svc, 165 plat_get_ns_image_entrypoint() & 0x1, 166 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 167 #endif 168 return spsr; 169 } 170 171 #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 172 static int load_sps_from_tb_fw_config(struct image_info *image_info) 173 { 174 void *dtb = (void *)image_info->image_base; 175 const char *compat_str = "arm,sp"; 176 const struct fdt_property *uuid; 177 uint32_t load_addr; 178 const char *name; 179 int sp_node; 180 int node; 181 182 node = fdt_node_offset_by_compatible(dtb, -1, compat_str); 183 if (node < 0) { 184 ERROR("Can't find %s in TB_FW_CONFIG", compat_str); 185 return -1; 186 } 187 188 fdt_for_each_subnode(sp_node, dtb, node) { 189 name = fdt_get_name(dtb, sp_node, NULL); 190 if (name == NULL) { 191 ERROR("Can't get name of node in dtb\n"); 192 return -1; 193 } 194 uuid = fdt_get_property(dtb, sp_node, "uuid", NULL); 195 if (uuid == NULL) { 196 ERROR("Can't find property uuid in node %s", name); 197 return -1; 198 } 199 if (fdt_read_uint32(dtb, sp_node, "load-address", 200 &load_addr) < 0) { 201 ERROR("Can't read load-address in node %s", name); 202 return -1; 203 } 204 if (qemu_io_register_sp_pkg(name, uuid->data, load_addr) < 0) { 205 return -1; 206 } 207 } 208 209 return 0; 210 } 211 #endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/ 212 213 static int qemu_bl2_handle_post_image_load(unsigned int image_id) 214 { 215 int err = 0; 216 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 217 #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE) 218 bl_mem_params_node_t *pager_mem_params = NULL; 219 bl_mem_params_node_t *paged_mem_params = NULL; 220 #endif 221 #if defined(SPD_spmd) 222 bl_mem_params_node_t *bl32_mem_params = NULL; 223 #endif 224 225 assert(bl_mem_params); 226 227 switch (image_id) { 228 case BL32_IMAGE_ID: 229 #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE) 230 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); 231 assert(pager_mem_params); 232 233 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); 234 assert(paged_mem_params); 235 236 err = parse_optee_header(&bl_mem_params->ep_info, 237 &pager_mem_params->image_info, 238 &paged_mem_params->image_info); 239 if (err != 0) { 240 WARN("OPTEE header parse error.\n"); 241 } 242 #endif 243 244 #if defined(SPMC_OPTEE) 245 /* 246 * Explicit zeroes to unused registers since they may have 247 * been populated by parse_optee_header() above. 248 * 249 * OP-TEE expects system DTB in x2 and TOS_FW_CONFIG in x0, 250 * the latter is filled in below for TOS_FW_CONFIG_ID and 251 * applies to any other SPMC too. 252 */ 253 bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE; 254 #elif defined(SPD_opteed) 255 /* 256 * OP-TEE expect to receive DTB address in x2. 257 * This will be copied into x2 by dispatcher. 258 */ 259 bl_mem_params->ep_info.args.arg3 = ARM_PRELOADED_DTB_BASE; 260 #elif defined(AARCH32_SP_OPTEE) 261 bl_mem_params->ep_info.args.arg0 = 262 bl_mem_params->ep_info.args.arg1; 263 bl_mem_params->ep_info.args.arg1 = 0; 264 bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE; 265 bl_mem_params->ep_info.args.arg3 = 0; 266 #endif 267 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry(); 268 break; 269 270 case BL33_IMAGE_ID: 271 #ifdef AARCH32_SP_OPTEE 272 /* AArch32 only core: OP-TEE expects NSec EP in register LR */ 273 pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); 274 assert(pager_mem_params); 275 pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; 276 #endif 277 278 #if ARM_LINUX_KERNEL_AS_BL33 279 /* 280 * According to the file ``Documentation/arm64/booting.txt`` of 281 * the Linux kernel tree, Linux expects the physical address of 282 * the device tree blob (DTB) in x0, while x1-x3 are reserved 283 * for future use and must be 0. 284 */ 285 bl_mem_params->ep_info.args.arg0 = 286 (u_register_t)ARM_PRELOADED_DTB_BASE; 287 bl_mem_params->ep_info.args.arg1 = 0U; 288 bl_mem_params->ep_info.args.arg2 = 0U; 289 bl_mem_params->ep_info.args.arg3 = 0U; 290 #else 291 /* BL33 expects to receive the primary CPU MPID (through r0) */ 292 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 293 #endif 294 295 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry(); 296 break; 297 #ifdef SPD_spmd 298 #if SPMD_SPM_AT_SEL2 299 case TB_FW_CONFIG_ID: 300 err = load_sps_from_tb_fw_config(&bl_mem_params->image_info); 301 break; 302 #endif 303 case TOS_FW_CONFIG_ID: 304 /* An SPMC expects TOS_FW_CONFIG in x0/r0 */ 305 bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); 306 bl32_mem_params->ep_info.args.arg0 = 307 bl_mem_params->image_info.image_base; 308 break; 309 #endif 310 default: 311 /* Do nothing in default case */ 312 break; 313 } 314 315 return err; 316 } 317 318 /******************************************************************************* 319 * This function can be used by the platforms to update/use image 320 * information for given `image_id`. 321 ******************************************************************************/ 322 int bl2_plat_handle_post_image_load(unsigned int image_id) 323 { 324 return qemu_bl2_handle_post_image_load(image_id); 325 } 326 327 uintptr_t plat_get_ns_image_entrypoint(void) 328 { 329 return NS_IMAGE_OFFSET; 330 } 331