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