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