/*
 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <desc_image_load.h>
#include <errno.h>
#include <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_IMAGE_NUM		2

#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)
{
	if ((header->magic == TEE_MAGIC_NUM_OPTEE) &&
		(header->version == 2) &&
		(header->nb_images <= OPTEE_MAX_IMAGE_NUM)) {
		return 1;
	}

	WARN("Not a known TEE, use default loading options.\n");
	return 0;
}

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