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 10 #include <arch_helpers.h> 11 #include <common/debug.h> 12 #include <common/desc_image_load.h> 13 #include <lib/optee_utils.h> 14 15 /* 16 * load_addr_hi and load_addr_lo: image load address. 17 * image_id: 0 - pager, 1 - paged 18 * size: image size in bytes. 19 */ 20 typedef struct optee_image { 21 uint32_t load_addr_hi; 22 uint32_t load_addr_lo; 23 uint32_t image_id; 24 uint32_t size; 25 } optee_image_t; 26 27 #define OPTEE_PAGER_IMAGE_ID 0 28 #define OPTEE_PAGED_IMAGE_ID 1 29 30 #define OPTEE_MAX_NUM_IMAGES 2u 31 32 #define TEE_MAGIC_NUM_OPTEE 0x4554504f 33 /* 34 * magic: header magic number. 35 * version: OPTEE header version: 36 * 1 - not supported 37 * 2 - supported 38 * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64. 39 * flags: unused currently. 40 * nb_images: number of images. 41 */ 42 typedef struct optee_header { 43 uint32_t magic; 44 uint8_t version; 45 uint8_t arch; 46 uint16_t flags; 47 uint32_t nb_images; 48 optee_image_t optee_image_list[]; 49 } optee_header_t; 50 51 /******************************************************************************* 52 * Check if it is a valid tee header 53 * Return 1 if valid 54 * Return 0 if invalid 55 ******************************************************************************/ 56 static inline int tee_validate_header(optee_header_t *header) 57 { 58 int valid = 0; 59 60 if ((header->magic == TEE_MAGIC_NUM_OPTEE) && 61 (header->version == 2u) && 62 (header->nb_images > 0u) && 63 (header->nb_images <= OPTEE_MAX_NUM_IMAGES)) { 64 valid = 1; 65 } 66 67 else { 68 WARN("Not a known TEE, use default loading options.\n"); 69 } 70 71 return valid; 72 } 73 74 /******************************************************************************* 75 * Parse the OPTEE image 76 * Return 0 on success or a negative error code otherwise. 77 ******************************************************************************/ 78 static int parse_optee_image(image_info_t *image_info, 79 optee_image_t *image) 80 { 81 uintptr_t init_load_addr, free_end, requested_end; 82 size_t init_size; 83 84 init_load_addr = ((uint64_t)image->load_addr_hi << 32) | 85 image->load_addr_lo; 86 init_size = image->size; 87 88 /* 89 * -1 indicates loader decided address; take our pre-mapped area 90 * for current image since arm-tf could not allocate memory dynamically 91 */ 92 if (init_load_addr == -1) 93 init_load_addr = image_info->image_base; 94 95 /* Check that the default end address doesn't overflow */ 96 if (check_uptr_overflow(image_info->image_base, 97 image_info->image_max_size - 1)) 98 return -1; 99 free_end = image_info->image_base + (image_info->image_max_size - 1); 100 101 /* Check that the image end address doesn't overflow */ 102 if (check_uptr_overflow(init_load_addr, init_size - 1)) 103 return -1; 104 requested_end = init_load_addr + (init_size - 1); 105 /* 106 * Check that the requested RAM location is within reserved 107 * space for OPTEE. 108 */ 109 if (!((init_load_addr >= image_info->image_base) && 110 (requested_end <= free_end))) { 111 WARN("The load address in optee header %p - %p is not in reserved area: %p - %p.\n", 112 (void *)init_load_addr, 113 (void *)(init_load_addr + init_size), 114 (void *)image_info->image_base, 115 (void *)(image_info->image_base + 116 image_info->image_max_size)); 117 return -1; 118 } 119 120 /* 121 * Remove the skip attr from image_info, the image will be loaded. 122 * The default attr in image_info is "IMAGE_ATTRIB_SKIP_LOADING", which 123 * mean the image will not be loaded. Here, we parse the header image to 124 * know that the extra image need to be loaded, so remove the skip attr. 125 */ 126 image_info->h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 127 128 /* Update image base and size of image_info */ 129 image_info->image_base = init_load_addr; 130 image_info->image_size = init_size; 131 132 return 0; 133 } 134 135 /******************************************************************************* 136 * Parse the OPTEE header 137 * Return 0 on success or a negative error code otherwise. 138 ******************************************************************************/ 139 int parse_optee_header(entry_point_info_t *header_ep, 140 image_info_t *pager_image_info, 141 image_info_t *paged_image_info) 142 143 { 144 optee_header_t *header; 145 int num, ret; 146 147 assert(header_ep); 148 header = (optee_header_t *)header_ep->pc; 149 assert(header); 150 151 /* Print the OPTEE header information */ 152 INFO("OPTEE ep=0x%x\n", (unsigned int)header_ep->pc); 153 INFO("OPTEE header info:\n"); 154 INFO(" magic=0x%x\n", header->magic); 155 INFO(" version=0x%x\n", header->version); 156 INFO(" arch=0x%x\n", header->arch); 157 INFO(" flags=0x%x\n", header->flags); 158 INFO(" nb_images=0x%x\n", header->nb_images); 159 160 /* 161 * OPTEE image has 3 types: 162 * 163 * 1. Plain OPTEE bin without header. 164 * Original bin without header, return directly, 165 * BL32_EXTRA1_IMAGE_ID and BL32_EXTRA2_IMAGE_ID will be skipped. 166 * 167 * 2. OPTEE bin with header bin, but no paging. 168 * Header available and nb_images = 1, remove skip attr for 169 * BL32_EXTRA1_IMAGE_ID. BL32_EXTRA1_IMAGE_ID will be loaded, 170 * and BL32_EXTRA2_IMAGE_ID be skipped. 171 * 172 * 3. OPTEE image with paging support. 173 * Header available and nb_images = 2, there are 3 bins: header, 174 * pager and pageable. Remove skip attr for BL32_EXTRA1_IMAGE_ID 175 * and BL32_EXTRA2_IMAGE_ID to load pager and paged bin. 176 */ 177 if (!tee_validate_header(header)) { 178 INFO("Invalid OPTEE header, set legacy mode.\n"); 179 #ifdef __aarch64__ 180 header_ep->args.arg0 = MODE_RW_64; 181 #else 182 header_ep->args.arg0 = MODE_RW_32; 183 #endif 184 return 0; 185 } 186 187 /* Parse OPTEE image */ 188 for (num = 0; num < header->nb_images; num++) { 189 if (header->optee_image_list[num].image_id == 190 OPTEE_PAGER_IMAGE_ID) { 191 ret = parse_optee_image(pager_image_info, 192 &header->optee_image_list[num]); 193 } else if (header->optee_image_list[num].image_id == 194 OPTEE_PAGED_IMAGE_ID) { 195 ret = parse_optee_image(paged_image_info, 196 &header->optee_image_list[num]); 197 } else { 198 ERROR("Parse optee image failed.\n"); 199 return -1; 200 } 201 202 if (ret != 0) 203 return -1; 204 } 205 206 /* 207 * Update "pc" value which should comes from pager image. After the 208 * header image is parsed, it will be unuseful, and the actual 209 * execution image after BL31 is pager image. 210 */ 211 header_ep->pc = pager_image_info->image_base; 212 213 /* 214 * The paged load address and size are populated in 215 * header image arguments so that can be read by the 216 * BL32 SPD. 217 */ 218 header_ep->args.arg1 = paged_image_info->image_base; 219 header_ep->args.arg2 = paged_image_info->image_size; 220 221 /* Set OPTEE runtime arch - aarch32/aarch64 */ 222 if (header->arch == 0) { 223 header_ep->args.arg0 = MODE_RW_32; 224 } else { 225 #ifdef __aarch64__ 226 header_ep->args.arg0 = MODE_RW_64; 227 #else 228 ERROR("Cannot boot an AArch64 OP-TEE\n"); 229 return -1; 230 #endif 231 } 232 233 return 0; 234 } 235