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