// SPDX-License-Identifier: MIT
/*
 * Copyright 2019 Advanced Micro Devices, Inc.
 */

#include <linux/device.h>
#include <linux/tee.h>
#include <linux/tee_drv.h>
#include <linux/psp-tee.h>
#include <linux/slab.h>
#include <linux/psp-sev.h>
#include "amdtee_if.h"
#include "amdtee_private.h"

static int tee_params_to_amd_params(struct tee_param *tee, u32 count,
				    struct tee_operation *amd)
{
	int i, ret = 0;
	u32 type;

	if (!count)
		return 0;

	if (!tee || !amd || count > TEE_MAX_PARAMS)
		return -EINVAL;

	amd->param_types = 0;
	for (i = 0; i < count; i++) {
		/* AMD TEE does not support meta parameter */
		if (tee[i].attr > TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT)
			return -EINVAL;

		amd->param_types |= ((tee[i].attr & 0xF) << i * 4);
	}

	for (i = 0; i < count; i++) {
		type = TEE_PARAM_TYPE_GET(amd->param_types, i);
		pr_debug("%s: type[%d] = 0x%x\n", __func__, i, type);

		if (type == TEE_OP_PARAM_TYPE_INVALID)
			return -EINVAL;

		if (type == TEE_OP_PARAM_TYPE_NONE)
			continue;

		/* It is assumed that all values are within 2^32-1 */
		if (type > TEE_OP_PARAM_TYPE_VALUE_INOUT) {
			u32 buf_id = get_buffer_id(tee[i].u.memref.shm);

			amd->params[i].mref.buf_id = buf_id;
			amd->params[i].mref.offset = tee[i].u.memref.shm_offs;
			amd->params[i].mref.size = tee[i].u.memref.size;
			pr_debug("%s: bufid[%d] = 0x%x, offset[%d] = 0x%x, size[%d] = 0x%x\n",
				 __func__,
				 i, amd->params[i].mref.buf_id,
				 i, amd->params[i].mref.offset,
				 i, amd->params[i].mref.size);
		} else {
			if (tee[i].u.value.c)
				pr_warn("%s: Discarding value c", __func__);

			amd->params[i].val.a = tee[i].u.value.a;
			amd->params[i].val.b = tee[i].u.value.b;
			pr_debug("%s: a[%d] = 0x%x, b[%d] = 0x%x\n", __func__,
				 i, amd->params[i].val.a,
				 i, amd->params[i].val.b);
		}
	}
	return ret;
}

static int amd_params_to_tee_params(struct tee_param *tee, u32 count,
				    struct tee_operation *amd)
{
	int i, ret = 0;
	u32 type;

	if (!count)
		return 0;

	if (!tee || !amd || count > TEE_MAX_PARAMS)
		return -EINVAL;

	/* Assumes amd->param_types is valid */
	for (i = 0; i < count; i++) {
		type = TEE_PARAM_TYPE_GET(amd->param_types, i);
		pr_debug("%s: type[%d] = 0x%x\n", __func__, i, type);

		if (type == TEE_OP_PARAM_TYPE_INVALID ||
		    type > TEE_OP_PARAM_TYPE_MEMREF_INOUT)
			return -EINVAL;

		if (type == TEE_OP_PARAM_TYPE_NONE ||
		    type == TEE_OP_PARAM_TYPE_VALUE_INPUT ||
		    type == TEE_OP_PARAM_TYPE_MEMREF_INPUT)
			continue;

		/*
		 * It is assumed that buf_id remains unchanged for
		 * both open_session and invoke_cmd call
		 */
		if (type > TEE_OP_PARAM_TYPE_MEMREF_INPUT) {
			tee[i].u.memref.shm_offs = amd->params[i].mref.offset;
			tee[i].u.memref.size = amd->params[i].mref.size;
			pr_debug("%s: bufid[%d] = 0x%x, offset[%d] = 0x%x, size[%d] = 0x%x\n",
				 __func__,
				 i, amd->params[i].mref.buf_id,
				 i, amd->params[i].mref.offset,
				 i, amd->params[i].mref.size);
		} else {
			/* field 'c' not supported by AMD TEE */
			tee[i].u.value.a = amd->params[i].val.a;
			tee[i].u.value.b = amd->params[i].val.b;
			tee[i].u.value.c = 0;
			pr_debug("%s: a[%d] = 0x%x, b[%d] = 0x%x\n",
				 __func__,
				 i, amd->params[i].val.a,
				 i, amd->params[i].val.b);
		}
	}
	return ret;
}

static DEFINE_MUTEX(ta_refcount_mutex);
static LIST_HEAD(ta_list);

static u32 get_ta_refcount(u32 ta_handle)
{
	struct amdtee_ta_data *ta_data;
	u32 count = 0;

	/* Caller must hold a mutex */
	list_for_each_entry(ta_data, &ta_list, list_node)
		if (ta_data->ta_handle == ta_handle)
			return ++ta_data->refcount;

	ta_data = kzalloc(sizeof(*ta_data), GFP_KERNEL);
	if (ta_data) {
		ta_data->ta_handle = ta_handle;
		ta_data->refcount = 1;
		count = ta_data->refcount;
		list_add(&ta_data->list_node, &ta_list);
	}

	return count;
}

static u32 put_ta_refcount(u32 ta_handle)
{
	struct amdtee_ta_data *ta_data;
	u32 count = 0;

	/* Caller must hold a mutex */
	list_for_each_entry(ta_data, &ta_list, list_node)
		if (ta_data->ta_handle == ta_handle) {
			count = --ta_data->refcount;
			if (count == 0) {
				list_del(&ta_data->list_node);
				kfree(ta_data);
				break;
			}
		}

	return count;
}

int handle_unload_ta(u32 ta_handle)
{
	struct tee_cmd_unload_ta cmd = {0};
	u32 status, count;
	int ret;

	if (!ta_handle)
		return -EINVAL;

	mutex_lock(&ta_refcount_mutex);

	count = put_ta_refcount(ta_handle);

	if (count) {
		pr_debug("unload ta: not unloading %u count %u\n",
			 ta_handle, count);
		ret = -EBUSY;
		goto unlock;
	}

	cmd.ta_handle = ta_handle;

	ret = psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA, (void *)&cmd,
				  sizeof(cmd), &status);
	if (!ret && status != 0) {
		pr_err("unload ta: status = 0x%x\n", status);
		ret = -EBUSY;
	} else {
		pr_debug("unloaded ta handle %u\n", ta_handle);
	}

unlock:
	mutex_unlock(&ta_refcount_mutex);
	return ret;
}

int handle_close_session(u32 ta_handle, u32 info)
{
	struct tee_cmd_close_session cmd = {0};
	u32 status;
	int ret;

	if (ta_handle == 0)
		return -EINVAL;

	cmd.ta_handle = ta_handle;
	cmd.session_info = info;

	ret = psp_tee_process_cmd(TEE_CMD_ID_CLOSE_SESSION, (void *)&cmd,
				  sizeof(cmd), &status);
	if (!ret && status != 0) {
		pr_err("close session: status = 0x%x\n", status);
		ret = -EBUSY;
	}

	return ret;
}

void handle_unmap_shmem(u32 buf_id)
{
	struct tee_cmd_unmap_shared_mem cmd = {0};
	u32 status;
	int ret;

	cmd.buf_id = buf_id;

	ret = psp_tee_process_cmd(TEE_CMD_ID_UNMAP_SHARED_MEM, (void *)&cmd,
				  sizeof(cmd), &status);
	if (!ret)
		pr_debug("unmap shared memory: buf_id %u status = 0x%x\n",
			 buf_id, status);
}

int handle_invoke_cmd(struct tee_ioctl_invoke_arg *arg, u32 sinfo,
		      struct tee_param *p)
{
	struct tee_cmd_invoke_cmd cmd = {0};
	int ret;

	if (!arg || (!p && arg->num_params))
		return -EINVAL;

	arg->ret_origin = TEEC_ORIGIN_COMMS;

	if (arg->session == 0) {
		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
		return -EINVAL;
	}

	ret = tee_params_to_amd_params(p, arg->num_params, &cmd.op);
	if (ret) {
		pr_err("invalid Params. Abort invoke command\n");
		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
		return ret;
	}

	cmd.ta_handle = get_ta_handle(arg->session);
	cmd.cmd_id = arg->func;
	cmd.session_info = sinfo;

	ret = psp_tee_process_cmd(TEE_CMD_ID_INVOKE_CMD, (void *)&cmd,
				  sizeof(cmd), &arg->ret);
	if (ret) {
		arg->ret = TEEC_ERROR_COMMUNICATION;
	} else {
		ret = amd_params_to_tee_params(p, arg->num_params, &cmd.op);
		if (unlikely(ret)) {
			pr_err("invoke command: failed to copy output\n");
			arg->ret = TEEC_ERROR_GENERIC;
			return ret;
		}
		arg->ret_origin = cmd.return_origin;
		pr_debug("invoke command: RO = 0x%x ret = 0x%x\n",
			 arg->ret_origin, arg->ret);
	}

	return ret;
}

int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id)
{
	struct tee_cmd_map_shared_mem *cmd;
	phys_addr_t paddr;
	int ret, i;
	u32 status;

	if (!count || !start || !buf_id)
		return -EINVAL;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	/* Size must be page aligned */
	for (i = 0; i < count ; i++) {
		if (!start[i].kaddr || (start[i].size & (PAGE_SIZE - 1))) {
			ret = -EINVAL;
			goto free_cmd;
		}

		if ((u64)start[i].kaddr & (PAGE_SIZE - 1)) {
			pr_err("map shared memory: page unaligned. addr 0x%llx",
			       (u64)start[i].kaddr);
			ret = -EINVAL;
			goto free_cmd;
		}
	}

	cmd->sg_list.count = count;

	/* Create buffer list */
	for (i = 0; i < count ; i++) {
		paddr = __psp_pa(start[i].kaddr);
		cmd->sg_list.buf[i].hi_addr = upper_32_bits(paddr);
		cmd->sg_list.buf[i].low_addr = lower_32_bits(paddr);
		cmd->sg_list.buf[i].size = start[i].size;
		cmd->sg_list.size += cmd->sg_list.buf[i].size;

		pr_debug("buf[%d]:hi addr = 0x%x\n", i,
			 cmd->sg_list.buf[i].hi_addr);
		pr_debug("buf[%d]:low addr = 0x%x\n", i,
			 cmd->sg_list.buf[i].low_addr);
		pr_debug("buf[%d]:size = 0x%x\n", i, cmd->sg_list.buf[i].size);
		pr_debug("list size = 0x%x\n", cmd->sg_list.size);
	}

	*buf_id = 0;

	ret = psp_tee_process_cmd(TEE_CMD_ID_MAP_SHARED_MEM, (void *)cmd,
				  sizeof(*cmd), &status);
	if (!ret && !status) {
		*buf_id = cmd->buf_id;
		pr_debug("mapped buffer ID = 0x%x\n", *buf_id);
	} else {
		pr_err("map shared memory: status = 0x%x\n", status);
		ret = -ENOMEM;
	}

free_cmd:
	kfree(cmd);

	return ret;
}

int handle_open_session(struct tee_ioctl_open_session_arg *arg, u32 *info,
			struct tee_param *p)
{
	struct tee_cmd_open_session cmd = {0};
	int ret;

	if (!arg || !info || (!p && arg->num_params))
		return -EINVAL;

	arg->ret_origin = TEEC_ORIGIN_COMMS;

	if (arg->session == 0) {
		arg->ret = TEEC_ERROR_GENERIC;
		return -EINVAL;
	}

	ret = tee_params_to_amd_params(p, arg->num_params, &cmd.op);
	if (ret) {
		pr_err("invalid Params. Abort open session\n");
		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
		return ret;
	}

	cmd.ta_handle = get_ta_handle(arg->session);
	*info = 0;

	ret = psp_tee_process_cmd(TEE_CMD_ID_OPEN_SESSION, (void *)&cmd,
				  sizeof(cmd), &arg->ret);
	if (ret) {
		arg->ret = TEEC_ERROR_COMMUNICATION;
	} else {
		ret = amd_params_to_tee_params(p, arg->num_params, &cmd.op);
		if (unlikely(ret)) {
			pr_err("open session: failed to copy output\n");
			arg->ret = TEEC_ERROR_GENERIC;
			return ret;
		}
		arg->ret_origin = cmd.return_origin;
		*info = cmd.session_info;
		pr_debug("open session: session info = 0x%x\n", *info);
	}

	pr_debug("open session: ret = 0x%x RO = 0x%x\n", arg->ret,
		 arg->ret_origin);

	return ret;
}

int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
{
	struct tee_cmd_unload_ta unload_cmd = {};
	struct tee_cmd_load_ta load_cmd = {};
	phys_addr_t blob;
	int ret;

	if (size == 0 || !data || !arg)
		return -EINVAL;

	blob = __psp_pa(data);
	if (blob & (PAGE_SIZE - 1)) {
		pr_err("load TA: page unaligned. blob 0x%llx", blob);
		return -EINVAL;
	}

	load_cmd.hi_addr = upper_32_bits(blob);
	load_cmd.low_addr = lower_32_bits(blob);
	load_cmd.size = size;

	mutex_lock(&ta_refcount_mutex);

	ret = psp_tee_process_cmd(TEE_CMD_ID_LOAD_TA, (void *)&load_cmd,
				  sizeof(load_cmd), &arg->ret);
	if (ret) {
		arg->ret_origin = TEEC_ORIGIN_COMMS;
		arg->ret = TEEC_ERROR_COMMUNICATION;
	} else if (arg->ret == TEEC_SUCCESS) {
		ret = get_ta_refcount(load_cmd.ta_handle);
		if (!ret) {
			arg->ret_origin = TEEC_ORIGIN_COMMS;
			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;

			/* Unload the TA on error */
			unload_cmd.ta_handle = load_cmd.ta_handle;
			psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
					    (void *)&unload_cmd,
					    sizeof(unload_cmd), &ret);
		} else {
			set_session_id(load_cmd.ta_handle, 0, &arg->session);
		}
	}
	mutex_unlock(&ta_refcount_mutex);

	pr_debug("load TA: TA handle = 0x%x, RO = 0x%x, ret = 0x%x\n",
		 load_cmd.ta_handle, arg->ret_origin, arg->ret);

	return 0;
}
