mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-23 13:36:05 +00:00

Enforce full include path for includes. Deprecate old paths. The following folders inside include/lib have been left unchanged: - include/lib/cpus/${ARCH} - include/lib/el3_runtime/${ARCH} The reason for this change is that having a global namespace for includes isn't a good idea. It defeats one of the advantages of having folders and it introduces problems that are sometimes subtle (because you may not know the header you are actually including if there are two of them). For example, this patch had to be created because two headers were called the same way:e0ea0928d5
("Fix gpio includes of mt8173 platform to avoid collision."). More recently, this patch has had similar problems:46f9b2c3a2
("drivers: add tzc380 support"). This problem was introduced in commit4ecca33988
("Move include and source files to logical locations"). At that time, there weren't too many headers so it wasn't a real issue. However, time has shown that this creates problems. Platforms that want to preserve the way they include headers may add the removed paths to PLAT_INCLUDES, but this is discouraged. Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
234 lines
6.6 KiB
C
234 lines
6.6 KiB
C
/*
|
|
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
|
|
#include <arch_helpers.h>
|
|
#include <common/debug.h>
|
|
#include <common/desc_image_load.h>
|
|
#include <lib/optee_utils.h>
|
|
|
|
/*
|
|
* load_addr_hi and load_addr_lo: image load address.
|
|
* image_id: 0 - pager, 1 - paged
|
|
* size: image size in bytes.
|
|
*/
|
|
typedef struct optee_image {
|
|
uint32_t load_addr_hi;
|
|
uint32_t load_addr_lo;
|
|
uint32_t image_id;
|
|
uint32_t size;
|
|
} optee_image_t;
|
|
|
|
#define OPTEE_PAGER_IMAGE_ID 0
|
|
#define OPTEE_PAGED_IMAGE_ID 1
|
|
|
|
#define OPTEE_MAX_NUM_IMAGES 2u
|
|
|
|
#define TEE_MAGIC_NUM_OPTEE 0x4554504f
|
|
/*
|
|
* magic: header magic number.
|
|
* version: OPTEE header version:
|
|
* 1 - not supported
|
|
* 2 - supported
|
|
* arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
|
|
* flags: unused currently.
|
|
* nb_images: number of images.
|
|
*/
|
|
typedef struct optee_header {
|
|
uint32_t magic;
|
|
uint8_t version;
|
|
uint8_t arch;
|
|
uint16_t flags;
|
|
uint32_t nb_images;
|
|
optee_image_t optee_image_list[];
|
|
} optee_header_t;
|
|
|
|
/*******************************************************************************
|
|
* Check if it is a valid tee header
|
|
* Return 1 if valid
|
|
* Return 0 if invalid
|
|
******************************************************************************/
|
|
static inline int tee_validate_header(optee_header_t *header)
|
|
{
|
|
int valid = 0;
|
|
|
|
if ((header->magic == TEE_MAGIC_NUM_OPTEE) &&
|
|
(header->version == 2u) &&
|
|
(header->nb_images > 0u) &&
|
|
(header->nb_images <= OPTEE_MAX_NUM_IMAGES)) {
|
|
valid = 1;
|
|
}
|
|
|
|
else {
|
|
WARN("Not a known TEE, use default loading options.\n");
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Parse the OPTEE image
|
|
* Return 0 on success or a negative error code otherwise.
|
|
******************************************************************************/
|
|
static int parse_optee_image(image_info_t *image_info,
|
|
optee_image_t *image)
|
|
{
|
|
uintptr_t init_load_addr, free_end, requested_end;
|
|
size_t init_size;
|
|
|
|
init_load_addr = ((uint64_t)image->load_addr_hi << 32) |
|
|
image->load_addr_lo;
|
|
init_size = image->size;
|
|
|
|
/*
|
|
* -1 indicates loader decided address; take our pre-mapped area
|
|
* for current image since arm-tf could not allocate memory dynamically
|
|
*/
|
|
if (init_load_addr == -1)
|
|
init_load_addr = image_info->image_base;
|
|
|
|
/* Check that the default end address doesn't overflow */
|
|
if (check_uptr_overflow(image_info->image_base,
|
|
image_info->image_max_size - 1))
|
|
return -1;
|
|
free_end = image_info->image_base + (image_info->image_max_size - 1);
|
|
|
|
/* Check that the image end address doesn't overflow */
|
|
if (check_uptr_overflow(init_load_addr, init_size - 1))
|
|
return -1;
|
|
requested_end = init_load_addr + (init_size - 1);
|
|
/*
|
|
* Check that the requested RAM location is within reserved
|
|
* space for OPTEE.
|
|
*/
|
|
if (!((init_load_addr >= image_info->image_base) &&
|
|
(requested_end <= free_end))) {
|
|
WARN("The load address in optee header %p - %p is not in reserved area: %p - %p.\n",
|
|
(void *)init_load_addr,
|
|
(void *)(init_load_addr + init_size),
|
|
(void *)image_info->image_base,
|
|
(void *)(image_info->image_base +
|
|
image_info->image_max_size));
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Remove the skip attr from image_info, the image will be loaded.
|
|
* The default attr in image_info is "IMAGE_ATTRIB_SKIP_LOADING", which
|
|
* mean the image will not be loaded. Here, we parse the header image to
|
|
* know that the extra image need to be loaded, so remove the skip attr.
|
|
*/
|
|
image_info->h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
|
|
|
|
/* Update image base and size of image_info */
|
|
image_info->image_base = init_load_addr;
|
|
image_info->image_size = init_size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Parse the OPTEE header
|
|
* Return 0 on success or a negative error code otherwise.
|
|
******************************************************************************/
|
|
int parse_optee_header(entry_point_info_t *header_ep,
|
|
image_info_t *pager_image_info,
|
|
image_info_t *paged_image_info)
|
|
|
|
{
|
|
optee_header_t *header;
|
|
int num, ret;
|
|
|
|
assert(header_ep);
|
|
header = (optee_header_t *)header_ep->pc;
|
|
assert(header);
|
|
|
|
/* Print the OPTEE header information */
|
|
INFO("OPTEE ep=0x%x\n", (unsigned int)header_ep->pc);
|
|
INFO("OPTEE header info:\n");
|
|
INFO(" magic=0x%x\n", header->magic);
|
|
INFO(" version=0x%x\n", header->version);
|
|
INFO(" arch=0x%x\n", header->arch);
|
|
INFO(" flags=0x%x\n", header->flags);
|
|
INFO(" nb_images=0x%x\n", header->nb_images);
|
|
|
|
/*
|
|
* OPTEE image has 3 types:
|
|
*
|
|
* 1. Plain OPTEE bin without header.
|
|
* Original bin without header, return directly,
|
|
* BL32_EXTRA1_IMAGE_ID and BL32_EXTRA2_IMAGE_ID will be skipped.
|
|
*
|
|
* 2. OPTEE bin with header bin, but no paging.
|
|
* Header available and nb_images = 1, remove skip attr for
|
|
* BL32_EXTRA1_IMAGE_ID. BL32_EXTRA1_IMAGE_ID will be loaded,
|
|
* and BL32_EXTRA2_IMAGE_ID be skipped.
|
|
*
|
|
* 3. OPTEE image with paging support.
|
|
* Header available and nb_images = 2, there are 3 bins: header,
|
|
* pager and pageable. Remove skip attr for BL32_EXTRA1_IMAGE_ID
|
|
* and BL32_EXTRA2_IMAGE_ID to load pager and paged bin.
|
|
*/
|
|
if (!tee_validate_header(header)) {
|
|
INFO("Invalid OPTEE header, set legacy mode.\n");
|
|
#ifdef AARCH64
|
|
header_ep->args.arg0 = MODE_RW_64;
|
|
#else
|
|
header_ep->args.arg0 = MODE_RW_32;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/* Parse OPTEE image */
|
|
for (num = 0; num < header->nb_images; num++) {
|
|
if (header->optee_image_list[num].image_id ==
|
|
OPTEE_PAGER_IMAGE_ID) {
|
|
ret = parse_optee_image(pager_image_info,
|
|
&header->optee_image_list[num]);
|
|
} else if (header->optee_image_list[num].image_id ==
|
|
OPTEE_PAGED_IMAGE_ID) {
|
|
ret = parse_optee_image(paged_image_info,
|
|
&header->optee_image_list[num]);
|
|
} else {
|
|
ERROR("Parse optee image failed.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (ret != 0)
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Update "pc" value which should comes from pager image. After the
|
|
* header image is parsed, it will be unuseful, and the actual
|
|
* execution image after BL31 is pager image.
|
|
*/
|
|
header_ep->pc = pager_image_info->image_base;
|
|
|
|
/*
|
|
* The paged load address and size are populated in
|
|
* header image arguments so that can be read by the
|
|
* BL32 SPD.
|
|
*/
|
|
header_ep->args.arg1 = paged_image_info->image_base;
|
|
header_ep->args.arg2 = paged_image_info->image_size;
|
|
|
|
/* Set OPTEE runtime arch - aarch32/aarch64 */
|
|
if (header->arch == 0) {
|
|
header_ep->args.arg0 = MODE_RW_32;
|
|
} else {
|
|
#ifdef AARCH64
|
|
header_ep->args.arg0 = MODE_RW_64;
|
|
#else
|
|
ERROR("Cannot boot an AArch64 OP-TEE\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|