// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2017, Linaro Limited
 */
#include <bench.h>
#include <compiler.h>
#include <kernel/misc.h>
#include <kernel/mutex.h>
#include <kernel/pseudo_ta.h>
#include <malloc.h>
#include <mm/core_memprot.h>
#include <mm/mobj.h>
#include <mm/tee_mm.h>
#include <mm/tee_pager.h>
#include <mm/tee_mmu.h>
#include <optee_rpc_cmd.h>
#include <pta_benchmark.h>
#include <string.h>
#include <string_ext.h>
#include <stdio.h>
#include <trace.h>

#define TA_NAME		"benchmark.ta"
#define TA_PRINT_PREFIX	"Benchmark: "

static struct tee_ts_global *bench_ts_global;
static size_t bench_ts_size;

static struct mutex bench_reg_mu = MUTEX_INITIALIZER;
static struct mobj *bench_mobj;

static TEE_Result rpc_reg_global_buf(uint64_t type, paddr_t phta, size_t size)
{
	struct thread_param tpm = THREAD_PARAM_VALUE(IN, type, phta, size);

	return thread_rpc_cmd(OPTEE_RPC_CMD_BENCH_REG, 1, &tpm);
}

static TEE_Result alloc_benchmark_buffer(uint32_t type,
				TEE_Param p[TEE_NUM_PARAMS])
{
	TEE_Result res;

	if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_VALUE_INOUT) ||
		(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_VALUE_INPUT) ||
		(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) {
		return TEE_ERROR_BAD_PARAMETERS;
	}

	mutex_lock(&bench_reg_mu);

	/* Check if we have already registered buffer */
	if (bench_ts_global) {
		EMSG(TA_PRINT_PREFIX
			"timestamp buffer was already registered");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	bench_ts_size = sizeof(struct tee_ts_global) +
		p[1].value.a * sizeof(struct tee_ts_cpu_buf);
	if (!bench_ts_size) {
		EMSG(TA_PRINT_PREFIX
			"invalid timestamp buffer size");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	bench_mobj = thread_rpc_alloc_global_payload(bench_ts_size);
	if (!bench_mobj) {
		EMSG(TA_PRINT_PREFIX
			"can't create mobj for timestamp buffer");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_OUT_OF_MEMORY;
	}

	bench_ts_global = (struct tee_ts_global *)mobj_get_va(bench_mobj, 0);
	if (!bench_ts_global) {
		thread_rpc_free_global_payload(bench_mobj);
		bench_mobj = NULL;

		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	memset((void *)bench_ts_global, 0, bench_ts_size);
	bench_ts_global->cores = p[1].value.a;

	DMSG(TA_PRINT_PREFIX
		"allocated timestamp buffer, addr = %p",
		(void *)bench_ts_global);

	mutex_unlock(&bench_reg_mu);

	/* Send back to the optee linux kernel module */
	res = rpc_reg_global_buf(OPTEE_MSG_RPC_CMD_BENCH_REG_NEW,
			virt_to_phys((void *)bench_ts_global),
			bench_ts_size);

	p[0].value.a = virt_to_phys((void *)bench_ts_global);
	p[0].value.b = bench_ts_size;

	return res;
}

static TEE_Result get_benchmark_memref(uint32_t type,
				TEE_Param p[TEE_NUM_PARAMS])
{
	if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_VALUE_OUTPUT) ||
		(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) {
		return TEE_ERROR_BAD_PARAMETERS;
	}

	mutex_lock(&bench_reg_mu);

	DMSG(TA_PRINT_PREFIX "Sending back timestamp buffer paddr = %p",
		(void *)virt_to_phys((void *)bench_ts_global));

	if (bench_ts_global) {
		p[0].value.a = virt_to_phys((void *)bench_ts_global);
		p[0].value.b = bench_ts_size;
	} else {
		p[0].value.a = 0;
		p[0].value.b = 0;
	}

	mutex_unlock(&bench_reg_mu);

	return TEE_SUCCESS;
}

static TEE_Result unregister_benchmark(uint32_t type,
				TEE_Param p[TEE_NUM_PARAMS] __unused)
{
	TEE_Result res;

	if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) {
		return TEE_ERROR_BAD_PARAMETERS;
	}
	mutex_lock(&bench_reg_mu);

	DMSG(TA_PRINT_PREFIX "Unregister benchmark ts buffer paddr = %p",
		(void *)virt_to_phys((void *)bench_ts_global));
	bench_ts_global = NULL;

	mutex_unlock(&bench_reg_mu);

	res = rpc_reg_global_buf(OPTEE_MSG_RPC_CMD_BENCH_REG_DEL, 0, 0);

	thread_rpc_free_global_payload(bench_mobj);
	bench_mobj = NULL;

	return res;
}

static TEE_Result invoke_command(void *session_ctx __unused,
		uint32_t cmd_id, uint32_t param_types,
		TEE_Param params[TEE_NUM_PARAMS])
{
	switch (cmd_id) {
	case BENCHMARK_CMD_ALLOCATE_BUF:
		return alloc_benchmark_buffer(param_types, params);
	case BENCHMARK_CMD_GET_MEMREF:
		return get_benchmark_memref(param_types, params);
	case BENCHMARK_CMD_UNREGISTER:
		return unregister_benchmark(param_types, params);
	default:
		break;
	}

	return TEE_ERROR_BAD_PARAMETERS;
}

pseudo_ta_register(.uuid = BENCHMARK_UUID, .name = TA_NAME,
		   .flags = PTA_DEFAULT_FLAGS,
		   .invoke_command_entry_point = invoke_command);

void bm_timestamp(void)
{
	struct tee_ts_cpu_buf *cpu_buf;
	struct tee_time_st ts_data;
	uint64_t ts_i;
	void *ret_addr;
	uint32_t cur_cpu;
	uint32_t exceptions;

	if (!bench_ts_global)
		return;

	exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
	cur_cpu = get_core_pos();

	if (cur_cpu >= bench_ts_global->cores) {
		thread_unmask_exceptions(exceptions);
		return;
	}

	ret_addr = __builtin_return_address(0);

	cpu_buf = &bench_ts_global->cpu_buf[cur_cpu];
	ts_i = cpu_buf->head++;
	ts_data.cnt = read_pmccntr() * TEE_BENCH_DIVIDER;
	ts_data.addr = (uintptr_t)ret_addr;
	ts_data.src = TEE_BENCH_CORE;
	cpu_buf->stamps[ts_i & TEE_BENCH_MAX_MASK] = ts_data;

	thread_unmask_exceptions(exceptions);
}
