// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2019, Linaro Limited
 */

#include <trace.h>
#include <utee_syscalls.h>
#include <pta_system.h>

#include "sys.h"

int trace_level = TRACE_LEVEL;
const char trace_ext_prefix[]  = "LD";

static uint32_t sess;

void __panic(const char *file __maybe_unused, const int line __maybe_unused,
	     const char *func __maybe_unused)
{
	if (!file && !func)
		EMSG_RAW("Panic");
	else
		EMSG_RAW("Panic at %s:%d %s%s%s",
			 file ? file : "?", file ? line : 0,
			 func ? "<" : "", func ? func : "", func ? ">" : "");

	utee_panic(1);
	/*NOTREACHED*/
	while (true)
		;
}

void sys_return_cleanup(void)
{
	if (sess) {
		if (utee_close_ta_session(sess))
			panic();
		sess = 0;
	}

	utee_return(0);
	/*NOTREACHED*/
	while (true)
		;
}

static TEE_Result invoke_sys_ta(uint32_t cmdid, struct utee_params *params)
{
	TEE_Result res = TEE_SUCCESS;
	uint32_t ret_orig = 0;

	if (!sess) {
		uint32_t s = 0;

		res = utee_open_ta_session(&(const TEE_UUID)PTA_SYSTEM_UUID,
					   0, NULL, &s, &ret_orig);
		if (res)
			return res;
		sess = s;
	}

	return utee_invoke_ta_command(sess, 0, cmdid, params, &ret_orig);
}

TEE_Result sys_map_zi(size_t num_bytes, uint32_t flags, vaddr_t *va,
		      size_t pad_begin, size_t pad_end)
{
	TEE_Result res = TEE_SUCCESS;
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INOUT,
					 TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_NONE),
	};
	uint32_t r[2] = { 0 };

	params.vals[0] = num_bytes;
	params.vals[1] = flags;
	reg_pair_from_64(*va, r, r + 1);
	params.vals[2] = r[0];
	params.vals[3] = r[1];
	params.vals[4] = pad_begin;
	params.vals[5] = pad_end;

	res = invoke_sys_ta(PTA_SYSTEM_MAP_ZI, &params);
	if (!res)
		*va = reg_pair_to_64(params.vals[2], params.vals[3]);
	return res;
}

TEE_Result sys_unmap(vaddr_t va, size_t num_bytes)
{
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE),
	};
	uint32_t r[2] = { 0 };

	params.vals[0] = num_bytes;
	reg_pair_from_64(va, r, r + 1);
	params.vals[2] = r[0];
	params.vals[3] = r[1];

	return invoke_sys_ta(PTA_SYSTEM_UNMAP, &params);
}

TEE_Result sys_open_ta_bin(const TEE_UUID *uuid, uint32_t *handle)
{
	TEE_Result res = TEE_SUCCESS;
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					 TEE_PARAM_TYPE_VALUE_OUTPUT,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE),
	};

	params.vals[0] = (vaddr_t)uuid;
	params.vals[1] = sizeof(*uuid);

	res = invoke_sys_ta(PTA_SYSTEM_OPEN_TA_BINARY, &params);
	if (!res)
		*handle = params.vals[2];
	return res;
}

TEE_Result sys_close_ta_bin(uint32_t handle)
{
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE),
	};

	params.vals[0] = handle;

	return invoke_sys_ta(PTA_SYSTEM_CLOSE_TA_BINARY, &params);
}

TEE_Result sys_map_ta_bin(vaddr_t *va, size_t num_bytes, uint32_t flags,
			  uint32_t handle, size_t offs, size_t pad_begin,
			  size_t pad_end)
{
	TEE_Result res = TEE_SUCCESS;
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INOUT,
					 TEE_PARAM_TYPE_VALUE_INPUT),
	};
	uint32_t r[2] = { 0 };

	params.vals[0] = handle;
	params.vals[1] = flags;
	params.vals[2] = offs;
	params.vals[3] = num_bytes;
	reg_pair_from_64(*va, r, r + 1);
	params.vals[4] = r[0];
	params.vals[5] = r[1];
	params.vals[6] = pad_begin;
	params.vals[7] = pad_end;

	res = invoke_sys_ta(PTA_SYSTEM_MAP_TA_BINARY, &params);
	if (!res)
		*va = reg_pair_to_64(params.vals[4], params.vals[5]);
	return res;
}


TEE_Result sys_copy_from_ta_bin(void *dst, size_t num_bytes, uint32_t handle,
				size_t offs)
{
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_MEMREF_OUTPUT,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE),
	};

	params.vals[0] = handle;
	params.vals[1] = offs;
	params.vals[2] = (vaddr_t)dst;
	params.vals[3] = num_bytes;

	return invoke_sys_ta(PTA_SYSTEM_COPY_FROM_TA_BINARY, &params);
}

TEE_Result sys_set_prot(vaddr_t va, size_t num_bytes, uint32_t flags)
{
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_NONE,
					 TEE_PARAM_TYPE_NONE),
	};
	uint32_t r[2] = { 0 };

	params.vals[0] = num_bytes;
	params.vals[1] = flags;
	reg_pair_from_64(va, r, r + 1);
	params.vals[2] = r[0];
	params.vals[3] = r[1];

	return invoke_sys_ta(PTA_SYSTEM_SET_PROT, &params);
}

TEE_Result sys_remap(vaddr_t old_va, vaddr_t *new_va, size_t num_bytes,
		     size_t pad_begin, size_t pad_end)
{
	TEE_Result res = TEE_SUCCESS;
	struct utee_params params = {
		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INPUT,
					 TEE_PARAM_TYPE_VALUE_INOUT,
					 TEE_PARAM_TYPE_VALUE_INPUT),
	};
	uint32_t r[2] = { 0 };

	params.vals[0] = num_bytes;
	reg_pair_from_64(old_va, r, r + 1);
	params.vals[2] = r[0];
	params.vals[3] = r[1];
	reg_pair_from_64(*new_va, r, r + 1);
	params.vals[4] = r[0];
	params.vals[5] = r[1];
	params.vals[6] = pad_begin;
	params.vals[7] = pad_end;

	res = invoke_sys_ta(PTA_SYSTEM_REMAP, &params);
	if (!res)
		*new_va = reg_pair_to_64(params.vals[4], params.vals[5]);
	return res;
}
