// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2018-2020 Linaro Limited
 */

#define LOG_CATEGORY UCLASS_TEE

#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <tee.h>
#include <asm/cache.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>

/**
 * struct tee_uclass_priv - information of a TEE, stored by the uclass
 *
 * @list_shm:	list of structe tee_shm representing memory blocks shared
 *		with the TEE.
 */
struct tee_uclass_priv {
	struct list_head list_shm;
};

static const struct tee_driver_ops *tee_get_ops(struct udevice *dev)
{
	return device_get_ops(dev);
}

void tee_get_version(struct udevice *dev, struct tee_version_data *vers)
{
	tee_get_ops(dev)->get_version(dev, vers);
}

int tee_open_session(struct udevice *dev, struct tee_open_session_arg *arg,
		     uint num_param, struct tee_param *param)
{
	return tee_get_ops(dev)->open_session(dev, arg, num_param, param);
}

int tee_close_session(struct udevice *dev, u32 session)
{
	return tee_get_ops(dev)->close_session(dev, session);
}

int tee_invoke_func(struct udevice *dev, struct tee_invoke_arg *arg,
		    uint num_param, struct tee_param *param)
{
	return tee_get_ops(dev)->invoke_func(dev, arg, num_param, param);
}

int __tee_shm_add(struct udevice *dev, ulong align, void *addr, ulong size,
		  u32 flags, struct tee_shm **shmp)
{
	struct tee_shm *shm;
	void *p = addr;
	int rc;

	if (flags & TEE_SHM_ALLOC) {
		if (align)
			p = memalign(align, size);
		else
			p = malloc(size);
	}
	if (!p)
		return -ENOMEM;

	shm = calloc(1, sizeof(*shm));
	if (!shm) {
		rc = -ENOMEM;
		goto err;
	}

	shm->dev = dev;
	shm->addr = p;
	shm->size = size;
	shm->flags = flags;

	if (flags & TEE_SHM_SEC_REGISTER) {
		rc = tee_get_ops(dev)->shm_register(dev, shm);
		if (rc)
			goto err;
	}

	if (flags & TEE_SHM_REGISTER) {
		struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);

		list_add(&shm->link, &priv->list_shm);
	}

	*shmp = shm;

	return 0;
err:
	free(shm);
	if (flags & TEE_SHM_ALLOC)
		free(p);

	return rc;
}

int tee_shm_alloc(struct udevice *dev, ulong size, u32 flags,
		  struct tee_shm **shmp)
{
	u32 f = flags;

	f |= TEE_SHM_SEC_REGISTER | TEE_SHM_REGISTER | TEE_SHM_ALLOC;

	return __tee_shm_add(dev, 0, NULL, size, f, shmp);
}

int tee_shm_register(struct udevice *dev, void *addr, ulong size, u32 flags,
		     struct tee_shm **shmp)
{
	u32 f = flags & ~TEE_SHM_ALLOC;

	f |= TEE_SHM_SEC_REGISTER | TEE_SHM_REGISTER;

	return __tee_shm_add(dev, 0, addr, size, f, shmp);
}

void tee_shm_free(struct tee_shm *shm)
{
	if (!shm)
		return;

	if (shm->flags & TEE_SHM_SEC_REGISTER)
		tee_get_ops(shm->dev)->shm_unregister(shm->dev, shm);

	if (shm->flags & TEE_SHM_REGISTER)
		list_del(&shm->link);

	if (shm->flags & TEE_SHM_ALLOC)
		free(shm->addr);

	free(shm);
}

bool tee_shm_is_registered(struct tee_shm *shm, struct udevice *dev)
{
	struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);
	struct tee_shm *s;

	list_for_each_entry(s, &priv->list_shm, link)
		if (s == shm)
			return true;

	return false;
}

struct udevice *tee_find_device(struct udevice *start,
				int (*match)(struct tee_version_data *vers,
					     const void *data),
				const void *data,
				struct tee_version_data *vers)
{
	struct udevice *dev = start;
	struct tee_version_data lv;
	struct tee_version_data *v = vers ? vers : &lv;

	if (!dev)
		uclass_find_first_device(UCLASS_TEE, &dev);
	else
		uclass_find_next_device(&dev);

	for (; dev; uclass_find_next_device(&dev)) {
		if (device_probe(dev))
			continue;
		tee_get_ops(dev)->get_version(dev, v);
		if (!match || match(v, data))
			return dev;
	}

	return NULL;
}

static int tee_pre_probe(struct udevice *dev)
{
	struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);

	INIT_LIST_HEAD(&priv->list_shm);

	return 0;
}

static int tee_pre_remove(struct udevice *dev)
{
	struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);
	struct tee_shm *shm;

	/*
	 * Any remaining shared memory must be unregistered now as U-Boot
	 * is about to hand over to the next stage and that memory will be
	 * reused.
	 */
	while (!list_empty(&priv->list_shm)) {
		shm = list_first_entry(&priv->list_shm, struct tee_shm, link);
		debug("%s: freeing leftover shm %p (size %lu, flags %#x)\n",
		      __func__, (void *)shm, shm->size, shm->flags);
		tee_shm_free(shm);
	}

	return 0;
}

UCLASS_DRIVER(tee) = {
	.id = UCLASS_TEE,
	.name = "tee",
	.per_device_auto	= sizeof(struct tee_uclass_priv),
	.pre_probe = tee_pre_probe,
	.pre_remove = tee_pre_remove,
};

void tee_optee_ta_uuid_from_octets(struct tee_optee_ta_uuid *d,
				   const u8 s[TEE_UUID_LEN])
{
	d->time_low = ((u32)s[0] << 24) | ((u32)s[1] << 16) |
		      ((u32)s[2] << 8) | s[3],
	d->time_mid = ((u32)s[4] << 8) | s[5];
	d->time_hi_and_version = ((u32)s[6] << 8) | s[7];
	memcpy(d->clock_seq_and_node, s + 8, sizeof(d->clock_seq_and_node));
}

void tee_optee_ta_uuid_to_octets(u8 d[TEE_UUID_LEN],
				 const struct tee_optee_ta_uuid *s)
{
	d[0] = s->time_low >> 24;
	d[1] = s->time_low >> 16;
	d[2] = s->time_low >> 8;
	d[3] = s->time_low;
	d[4] = s->time_mid >> 8;
	d[5] = s->time_mid;
	d[6] = s->time_hi_and_version >> 8;
	d[7] = s->time_hi_and_version;
	memcpy(d + 8, s->clock_seq_and_node, sizeof(s->clock_seq_and_node));
}

void tee_flush_all_shm_dcache(struct udevice *dev)
{
	struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);
	struct tee_shm *s;

	list_for_each_entry(s, &priv->list_shm, link) {
		ulong start = rounddown((ulong)s->addr,
					CONFIG_SYS_CACHELINE_SIZE);
		ulong end = roundup((ulong)s->addr + s->size,
				    CONFIG_SYS_CACHELINE_SIZE);

		flush_dcache_range(start, end);
	}
}
