/*
 * 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;
}
