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

/*
 * APIs defined in this file are required to use __noprof attribute to
 * avoid any circular dependency during profiling. So this requirement
 * prohibits these APIs to use standard library APIs as those can be
 * profiled too.
 */

#include <assert.h>
#include <user_ta_header.h>
#if defined(__KERNEL__)
#include <arm.h>
#include <kernel/panic.h>
#include <kernel/tee_ta_manager.h>
#include <kernel/thread.h>
#include <mm/core_mmu.h>
#else
#include <arm_user_sysreg.h>
#include <setjmp.h>
#include <utee_syscalls.h>
#endif
#include "ftrace.h"

#define DURATION_MAX_LEN		16

static const char hex_str[] = "0123456789abcdef";

static __noprof struct ftrace_buf *get_fbuf(void)
{
#if defined(__KERNEL__)
	int ct = thread_get_id_may_fail();
	struct tee_ta_session *s = NULL;
	struct thread_specific_data *tsd = NULL;

	if (ct == -1)
		return NULL;

	if (!(core_mmu_user_va_range_is_defined() &&
	      core_mmu_user_mapping_is_active()))
		return NULL;

	tsd = thread_get_tsd();
	s = TAILQ_FIRST(&tsd->sess_stack);

	if (!s || tsd->ctx != s->ctx)
		return NULL;

	if (s->fbuf && s->fbuf->syscall_trace_enabled &&
	    !s->fbuf->syscall_trace_suspended)
		return s->fbuf;
	else
		return NULL;
#else
	return &__ftrace_buf_start;
#endif
}

/*
 * This API shifts/moves ftrace buffer to create space for new dump
 * in case the buffer size falls short of actual dump.
 */
static void __noprof fbuf_shift(struct ftrace_buf *fbuf, size_t size)
{
	char *dst = (char *)fbuf + fbuf->buf_off;
	const char *src = (char *)fbuf + fbuf->buf_off + size;
	size_t n = 0;

	fbuf->curr_size -= size;

	for (n = 0; n < fbuf->curr_size; n++)
		dst[n] = src[n];
}

static size_t __noprof to_func_enter_fmt(char *buf, uint32_t ret_idx,
					 unsigned long pc)
{
	char *str = buf;
	uint32_t addr_size = 2 * sizeof(unsigned long);
	uint32_t i = 0;

	for (i = 0; i < (DURATION_MAX_LEN + ret_idx); i++)
		if (i == (DURATION_MAX_LEN - 2))
			*str++ = '|';
		else
			*str++ = ' ';

	*str++ = '0';
	*str++ = 'x';

	for (i = 0; i < addr_size; i++)
		*str++ = hex_str[(pc >> 4 * (addr_size - i - 1)) & 0xf];

	*str++ = '(';
	*str++ = ')';
	*str++ = ' ';
	*str++ = '{';
	*str++ = '\n';
	*str = '\0';

	return str - buf;
}

void __noprof ftrace_enter(unsigned long pc, unsigned long *lr)
{
	struct ftrace_buf *fbuf = NULL;
	size_t dump_size = 0;

	fbuf = get_fbuf();

	if (!fbuf || !fbuf->buf_off || !fbuf->max_size)
		return;

	dump_size = DURATION_MAX_LEN + fbuf->ret_idx +
			(2 * sizeof(unsigned long)) + 8;

	/*
	 * Check if we have enough space in ftrace buffer. If not then just
	 * remove oldest dump under the assumption that its the least
	 * interesting data.
	 */
	if ((fbuf->curr_size + dump_size) > fbuf->max_size)
		fbuf_shift(fbuf, dump_size);

	fbuf->curr_size += to_func_enter_fmt((char *)fbuf + fbuf->buf_off +
					     fbuf->curr_size, fbuf->ret_idx,
					     pc);

	if (fbuf->ret_idx < FTRACE_RETFUNC_DEPTH) {
		fbuf->ret_stack[fbuf->ret_idx] = *lr;
		fbuf->begin_time[fbuf->ret_idx] = read_cntpct();
		fbuf->ret_idx++;
	} else {
		/*
		 * This scenario isn't expected as function call depth
		 * shouldn't be more than FTRACE_RETFUNC_DEPTH.
		 */
#if defined(__KERNEL__)
		panic();
#else
		utee_panic(0);
#endif
	}

	*lr = (unsigned long)&__ftrace_return;
}

static void __noprof ftrace_duration(char *buf, uint64_t start, uint64_t end)
{
	uint32_t max_us = CFG_FTRACE_US_MS;
	uint32_t cntfrq = read_cntfrq();
	uint64_t ticks = end - start;
	uint32_t ms = 0;
	uint32_t us = 0;
	uint32_t ns = 0;
	uint32_t frac = 0;
	uint32_t in = 0;
	char unit = 'u';
	int i = 0;

	ticks = ticks * 1000000000 / cntfrq;
	us = ticks / 1000;
	ns = ticks % 1000;

	if (max_us && us >= max_us) {
		/* Display value in milliseconds */
		unit = 'm';
		ms = us / 1000;
		us = us % 1000;
		frac = us;
		in = ms;
	} else {
		/* Display value in microseconds */
		frac = ns;
		in = us;
	}

	*buf-- = 's';
	*buf-- = unit;
	*buf-- = ' ';

	COMPILE_TIME_ASSERT(DURATION_MAX_LEN == 16);
	if (in > 999999) {
		/* Not enough space to print the value */
		for (i = 0; i < 10; i++)
			*buf-- = '-';
		return;
	}

	for (i = 0; i < 3; i++) {
		*buf-- = hex_str[frac % 10];
		frac /= 10;
	}

	*buf-- = '.';

	while (in) {
		*buf-- = hex_str[in % 10];
		in /= 10;
	}
}

unsigned long __noprof ftrace_return(void)
{
	struct ftrace_buf *fbuf = NULL;
	size_t dump_size = 0;
	char *curr_buf = NULL;
	char *dur_loc = NULL;
	uint32_t i = 0;

	fbuf = get_fbuf();

	/* Check for valid return index */
	if (fbuf && fbuf->ret_idx && fbuf->ret_idx <= FTRACE_RETFUNC_DEPTH)
		fbuf->ret_idx--;
	else
		return 0;

	curr_buf = (char *)fbuf + fbuf->buf_off + fbuf->curr_size;

	/*
	 * Check for '{' symbol as it represents if it is an exit from current
	 * or nested function. If exit is from current function, than exit dump
	 * via ';' symbol else exit dump via '}' symbol.
	 */
	if (*(curr_buf - 2) == '{') {
		*(curr_buf - 3) = ';';
		*(curr_buf - 2) = '\n';
		*(curr_buf - 1) = '\0';
		fbuf->curr_size -= 1;

		dur_loc = curr_buf - (fbuf->ret_idx +
				      (2 * sizeof(unsigned long)) + 11);
		ftrace_duration(dur_loc, fbuf->begin_time[fbuf->ret_idx],
				read_cntpct());
	} else {
		dump_size = DURATION_MAX_LEN + fbuf->ret_idx + 3;
		if ((fbuf->curr_size + dump_size) > fbuf->max_size)
			fbuf_shift(fbuf, dump_size);

		curr_buf = (char *)fbuf + fbuf->buf_off + fbuf->curr_size;

		for (i = 0; i < (DURATION_MAX_LEN + fbuf->ret_idx); i++)
			if (i == (DURATION_MAX_LEN - 2))
				*curr_buf++ = '|';
			else
				*curr_buf++ = ' ';

		*curr_buf++ = '}';
		*curr_buf++ = '\n';
		*curr_buf = '\0';

		fbuf->curr_size += dump_size - 1;

		dur_loc = curr_buf - fbuf->ret_idx - 6;
		ftrace_duration(dur_loc, fbuf->begin_time[fbuf->ret_idx],
				read_cntpct());
	}

	return fbuf->ret_stack[fbuf->ret_idx];
}

#if !defined(__KERNEL__)
void __noprof ftrace_longjmp(unsigned int *ret_idx)
{
	while (__ftrace_buf_start.ret_idx > *ret_idx)
		ftrace_return();
}

void __noprof ftrace_setjmp(unsigned int *ret_idx)
{
	*ret_idx = __ftrace_buf_start.ret_idx;
}
#endif
