// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 Linaro
 * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
 */

#include <common.h>
#include <malloc.h>
#include <linux/libfdt.h>
#include <tee/optee.h>

#define optee_hdr_err_msg \
	"OPTEE verification error:" \
	"\n\thdr=%p image=0x%08lx magic=0x%08x tzdram 0x%08lx-0x%08lx " \
	"\n\theader lo=0x%08x hi=0x%08x size=0x%08lx arch=0x%08x" \
	"\n\tuimage params 0x%08lx-0x%08lx\n"

int optee_verify_image(struct optee_header *hdr, unsigned long tzdram_start,
		       unsigned long tzdram_len, unsigned long image_len)
{
	unsigned long tzdram_end = tzdram_start + tzdram_len;
	uint32_t tee_file_size;

	tee_file_size = hdr->init_size + hdr->paged_size +
			sizeof(struct optee_header);

	if (hdr->magic != OPTEE_MAGIC ||
	    hdr->version != OPTEE_VERSION ||
	    hdr->init_load_addr_hi > tzdram_end ||
	    hdr->init_load_addr_lo < tzdram_start ||
	    tee_file_size > tzdram_len ||
	    tee_file_size != image_len ||
	    (hdr->init_load_addr_lo + tee_file_size) > tzdram_end) {
		return -EINVAL;
	}

	return 0;
}

int optee_verify_bootm_image(unsigned long image_addr,
			     unsigned long image_load_addr,
			     unsigned long image_len)
{
	struct optee_header *hdr = (struct optee_header *)image_addr;
	unsigned long tzdram_start = CONFIG_OPTEE_TZDRAM_BASE;
	unsigned long tzdram_len = CONFIG_OPTEE_TZDRAM_SIZE;

	int ret;

	ret = optee_verify_image(hdr, tzdram_start, tzdram_len, image_len);
	if (ret)
		goto error;

	if (image_load_addr + sizeof(*hdr) != hdr->init_load_addr_lo) {
		ret = -EINVAL;
		goto error;
	}

	return ret;
error:
	printf(optee_hdr_err_msg, hdr, image_addr, hdr->magic, tzdram_start,
	       tzdram_start + tzdram_len, hdr->init_load_addr_lo,
	       hdr->init_load_addr_hi, image_len, hdr->arch, image_load_addr,
	       image_load_addr + image_len);

	return ret;
}

#if defined(CONFIG_OF_LIBFDT)
static int optee_copy_firmware_node(const void *old_blob, void *fdt_blob)
{
	int old_offs, offs, ret, len;
	const void *prop;

	old_offs = fdt_path_offset(old_blob, "/firmware/optee");
	if (old_offs < 0) {
		debug("Original OP-TEE Device Tree node not found");
		return old_offs;
	}

	offs = fdt_path_offset(fdt_blob, "/firmware");
	if (offs < 0) {
		offs = fdt_path_offset(fdt_blob, "/");
		if (offs < 0)
			return offs;

		offs = fdt_add_subnode(fdt_blob, offs, "firmware");
		if (offs < 0)
			return offs;
	}

	offs = fdt_add_subnode(fdt_blob, offs, "optee");
	if (offs < 0)
		return ret;

	/* copy the compatible property */
	prop = fdt_getprop(old_blob, old_offs, "compatible", &len);
	if (!prop) {
		debug("missing OP-TEE compatible property");
		return -EINVAL;
	}

	ret = fdt_setprop(fdt_blob, offs, "compatible", prop, len);
	if (ret < 0)
		return ret;

	/* copy the method property */
	prop = fdt_getprop(old_blob, old_offs, "method", &len);
	if (!prop) {
		debug("missing OP-TEE method property");
		return -EINVAL;
	}

	ret = fdt_setprop(fdt_blob, offs, "method", prop, len);
	if (ret < 0)
		return ret;

	return 0;
}

int optee_copy_fdt_nodes(const void *old_blob, void *new_blob)
{
	int nodeoffset, subnode, ret;
	struct fdt_resource res;

	if (fdt_check_header(old_blob))
		return -EINVAL;

	if (fdt_check_header(new_blob))
		return -EINVAL;

	/* only proceed if there is an /firmware/optee node */
	if (fdt_path_offset(old_blob, "/firmware/optee") < 0) {
		debug("No OP-TEE firmware node in old fdt, nothing to do");
		return 0;
	}

	/*
	 * Do not proceed if the target dt already has an OP-TEE node.
	 * In this case assume that the system knows better somehow,
	 * so do not interfere.
	 */
	if (fdt_path_offset(new_blob, "/firmware/optee") >= 0) {
		debug("OP-TEE Device Tree node already exists in target");
		return 0;
	}

	ret = optee_copy_firmware_node(old_blob, new_blob);
	if (ret < 0) {
		printf("Failed to add OP-TEE firmware node\n");
		return ret;
	}

	/* optee inserts its memory regions as reserved-memory nodes */
	nodeoffset = fdt_subnode_offset(old_blob, 0, "reserved-memory");
	if (nodeoffset >= 0) {
		subnode = fdt_first_subnode(old_blob, nodeoffset);
		while (subnode >= 0) {
			const char *name = fdt_get_name(old_blob,
							subnode, NULL);
			if (!name)
				return -EINVAL;

			/* only handle optee reservations */
			if (strncmp(name, "optee", 5))
				continue;

			/* check if this subnode has a reg property */
			ret = fdt_get_resource(old_blob, subnode, "reg", 0,
					       &res);
			if (!ret) {
				struct fdt_memory carveout = {
					.start = res.start,
					.end = res.end,
				};
				char *oldname, *nodename, *tmp;

				oldname = strdup(name);
				if (!oldname)
					return -ENOMEM;

				tmp = oldname;
				nodename = strsep(&tmp, "@");
				if (!nodename) {
					free(oldname);
					return -EINVAL;
				}

				ret = fdtdec_add_reserved_memory(new_blob,
								 nodename,
								 &carveout,
								 NULL);
				free(oldname);

				if (ret < 0)
					return ret;
			}

			subnode = fdt_next_subnode(old_blob, subnode);
		}
	}

	return 0;
}
#endif
