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