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