// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2012 The Chromium OS Authors.
 */

#include <common.h>
#include <mapmem.h>
#include <time.h>
#include <trace.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/sections.h>

DECLARE_GLOBAL_DATA_PTR;

static char trace_enabled __section(".data");
static char trace_inited __section(".data");

/* The header block at the start of the trace memory area */
struct trace_hdr {
	int func_count;		/* Total number of function call sites */
	u64 call_count;		/* Total number of tracked function calls */
	u64 untracked_count;	/* Total number of untracked function calls */
	int funcs_used;		/* Total number of functions used */

	/*
	 * Call count for each function. This is indexed by the word offset
	 * of the function from gd->relocaddr
	 */
	uintptr_t *call_accum;

	/* Function trace list */
	struct trace_call *ftrace;	/* The function call records */
	ulong ftrace_size;	/* Num. of ftrace records we have space for */
	ulong ftrace_count;	/* Num. of ftrace records written */
	ulong ftrace_too_deep_count;	/* Functions that were too deep */

	int depth;		/* Depth of function calls */
	int depth_limit;	/* Depth limit to trace to */
	int max_depth;		/* Maximum depth seen so far */
	int min_depth;		/* Minimum depth seen so far */
	bool trace_locked;	/* Used to detect recursive tracing */
};

/* Pointer to start of trace buffer */
static struct trace_hdr *hdr __section(".data");

static inline uintptr_t __attribute__((no_instrument_function))
		func_ptr_to_num(void *func_ptr)
{
	uintptr_t offset = (uintptr_t)func_ptr;

#ifdef CONFIG_SANDBOX
	offset -= (uintptr_t)_init;
#else
	if (gd->flags & GD_FLG_RELOC)
		offset -= gd->relocaddr;
	else
		offset -= CONFIG_TEXT_BASE;
#endif
	return offset / FUNC_SITE_SIZE;
}

#if defined(CONFIG_EFI_LOADER) && (defined(CONFIG_ARM) || defined(CONFIG_RISCV))

/**
 * trace_gd - the value of the gd register
 */
static volatile gd_t *trace_gd;

/**
 * trace_save_gd() - save the value of the gd register
 */
static void notrace trace_save_gd(void)
{
	trace_gd = gd;
}

/**
 * trace_swap_gd() - swap between U-Boot and application gd register value
 *
 * An UEFI application may change the value of the register that gd lives in.
 * But some of our functions like get_ticks() access this register. So we
 * have to set the gd register to the U-Boot value when entering a trace
 * point and set it back to the application value when exiting the trace point.
 */
static void notrace trace_swap_gd(void)
{
	volatile gd_t *temp_gd = trace_gd;

	trace_gd = gd;
	set_gd(temp_gd);
}

#else

static void notrace trace_save_gd(void)
{
}

static void notrace trace_swap_gd(void)
{
}

#endif

static void notrace add_ftrace(void *func_ptr, void *caller, ulong flags)
{
	if (hdr->depth > hdr->depth_limit) {
		hdr->ftrace_too_deep_count++;
		return;
	}
	if (hdr->ftrace_count < hdr->ftrace_size) {
		struct trace_call *rec = &hdr->ftrace[hdr->ftrace_count];

		rec->func = func_ptr_to_num(func_ptr);
		rec->caller = func_ptr_to_num(caller);
		rec->flags = flags | (timer_get_us() & FUNCF_TIMESTAMP_MASK);
	}
	hdr->ftrace_count++;
}

/**
 * __cyg_profile_func_enter() - record function entry
 *
 * We add to our tally for this function and add to the list of called
 * functions.
 *
 * @func_ptr:	pointer to function being entered
 * @caller:	pointer to function which called this function
 */
void notrace __cyg_profile_func_enter(void *func_ptr, void *caller)
{
	if (trace_enabled) {
		int func;

		if (hdr->trace_locked) {
			trace_enabled = 0;
			puts("trace: recursion detected, disabling\n");
			hdr->trace_locked = false;
			return;
		}

		hdr->trace_locked = true;
		trace_swap_gd();
		add_ftrace(func_ptr, caller, FUNCF_ENTRY);
		func = func_ptr_to_num(func_ptr);
		if (func < hdr->func_count) {
			hdr->call_accum[func]++;
			hdr->call_count++;
		} else {
			hdr->untracked_count++;
		}
		hdr->depth++;
		if (hdr->depth > hdr->max_depth)
			hdr->max_depth = hdr->depth;
		trace_swap_gd();
		hdr->trace_locked = false;
	}
}

/**
 * __cyg_profile_func_exit() - record function exit
 *
 * @func_ptr:	pointer to function being entered
 * @caller:	pointer to function which called this function
 */
void notrace __cyg_profile_func_exit(void *func_ptr, void *caller)
{
	if (trace_enabled) {
		trace_swap_gd();
		hdr->depth--;
		add_ftrace(func_ptr, caller, FUNCF_EXIT);
		if (hdr->depth < hdr->min_depth)
			hdr->min_depth = hdr->depth;
		trace_swap_gd();
	}
}

/**
 * trace_list_functions() - produce a list of called functions
 *
 * The information is written into the supplied buffer - a header followed
 * by a list of function records.
 *
 * @buff:	buffer to place list into
 * @buff_size:	size of buffer
 * @needed:	returns size of buffer needed, which may be
 *		greater than buff_size if we ran out of space.
 * Return:	0 if ok, -ENOSPC if space was exhausted
 */
int trace_list_functions(void *buff, size_t buff_size, size_t *needed)
{
	struct trace_output_hdr *output_hdr = NULL;
	void *end, *ptr = buff;
	size_t func;
	size_t upto;

	end = buff ? buff + buff_size : NULL;

	/* Place some header information */
	if (ptr + sizeof(struct trace_output_hdr) < end)
		output_hdr = ptr;
	ptr += sizeof(struct trace_output_hdr);

	/* Add information about each function */
	for (func = upto = 0; func < hdr->func_count; func++) {
		size_t calls = hdr->call_accum[func];

		if (!calls)
			continue;

		if (ptr + sizeof(struct trace_output_func) < end) {
			struct trace_output_func *stats = ptr;

			stats->offset = func * FUNC_SITE_SIZE;
			stats->call_count = calls;
			upto++;
		}
		ptr += sizeof(struct trace_output_func);
	}

	/* Update the header */
	if (output_hdr) {
		output_hdr->rec_count = upto;
		output_hdr->type = TRACE_CHUNK_FUNCS;
	}

	/* Work out how must of the buffer we used */
	*needed = ptr - buff;
	if (ptr > end)
		return -ENOSPC;

	return 0;
}

/**
 * trace_list_functions() - produce a list of function calls
 *
 * The information is written into the supplied buffer - a header followed
 * by a list of function records.
 *
 * @buff:	buffer to place list into
 * @buff_size:	size of buffer
 * @needed:	returns size of buffer needed, which may be
 *		greater than buff_size if we ran out of space.
 * Return:	0 if ok, -ENOSPC if space was exhausted
 */
int trace_list_calls(void *buff, size_t buff_size, size_t *needed)
{
	struct trace_output_hdr *output_hdr = NULL;
	void *end, *ptr = buff;
	size_t rec, upto;
	size_t count;

	end = buff ? buff + buff_size : NULL;

	/* Place some header information */
	if (ptr + sizeof(struct trace_output_hdr) < end)
		output_hdr = ptr;
	ptr += sizeof(struct trace_output_hdr);

	/* Add information about each call */
	count = hdr->ftrace_count;
	if (count > hdr->ftrace_size)
		count = hdr->ftrace_size;
	for (rec = upto = 0; rec < count; rec++) {
		if (ptr + sizeof(struct trace_call) < end) {
			struct trace_call *call = &hdr->ftrace[rec];
			struct trace_call *out = ptr;

			out->func = call->func * FUNC_SITE_SIZE;
			out->caller = call->caller * FUNC_SITE_SIZE;
			out->flags = call->flags;
			upto++;
		}
		ptr += sizeof(struct trace_call);
	}

	/* Update the header */
	if (output_hdr) {
		memset(output_hdr, '\0', sizeof(*output_hdr));
		output_hdr->rec_count = upto;
		output_hdr->type = TRACE_CHUNK_CALLS;
		output_hdr->version = TRACE_VERSION;
		output_hdr->text_base = CONFIG_TEXT_BASE;
	}

	/* Work out how must of the buffer we used */
	*needed = ptr - buff;
	if (ptr > end)
		return -ENOSPC;

	return 0;
}

/**
 * trace_print_stats() - print basic information about tracing
 */
void trace_print_stats(void)
{
	ulong count;

#ifndef FTRACE
	puts("Warning: make U-Boot with FTRACE to enable function instrumenting.\n");
	puts("You will likely get zeroed data here\n");
#endif
	if (!trace_inited) {
		printf("Trace is disabled\n");
		return;
	}
	print_grouped_ull(hdr->func_count, 10);
	puts(" function sites\n");
	print_grouped_ull(hdr->call_count, 10);
	puts(" function calls\n");
	print_grouped_ull(hdr->untracked_count, 10);
	puts(" untracked function calls\n");
	count = min(hdr->ftrace_count, hdr->ftrace_size);
	print_grouped_ull(count, 10);
	puts(" traced function calls");
	if (hdr->ftrace_count > hdr->ftrace_size) {
		printf(" (%lu dropped due to overflow)",
		       hdr->ftrace_count - hdr->ftrace_size);
	}

	/* Add in minimum depth since the trace did not start at top level */
	printf("\n%15d maximum observed call depth\n",
	       hdr->max_depth - hdr->min_depth);
	printf("%15d call depth limit\n", hdr->depth_limit);
	print_grouped_ull(hdr->ftrace_too_deep_count, 10);
	puts(" calls not traced due to depth\n");
	print_grouped_ull(hdr->ftrace_size, 10);
	puts(" max function calls\n");
	printf("\ntrace buffer %lx call records %lx\n",
	       (ulong)map_to_sysmem(hdr), (ulong)map_to_sysmem(hdr->ftrace));
}

void notrace trace_set_enabled(int enabled)
{
	trace_enabled = enabled != 0;
}

static int get_func_count(void)
{
	/* Detect no support for mon_len since this means tracing cannot work */
	if (IS_ENABLED(CONFIG_SANDBOX) && !gd->mon_len) {
		puts("Tracing is not supported on this board\n");
		return -ENOTSUPP;
	}

	return gd->mon_len / FUNC_SITE_SIZE;
}

/**
 * trace_init() - initialize the tracing system and enable it
 *
 * @buff:	Pointer to trace buffer
 * @buff_size:	Size of trace buffer
 * Return:	0 if ok
 */
int notrace trace_init(void *buff, size_t buff_size)
{
	int func_count = get_func_count();
	size_t needed;
	int was_disabled = !trace_enabled;

	if (func_count < 0)
		return func_count;
	trace_save_gd();

	if (!was_disabled) {
#ifdef CONFIG_TRACE_EARLY
		ulong used, count;
		char *end;

		/*
		 * Copy over the early trace data if we have it. Disable
		 * tracing while we are doing this.
		 */
		trace_enabled = 0;
		hdr = map_sysmem(CONFIG_TRACE_EARLY_ADDR,
				 CONFIG_TRACE_EARLY_SIZE);
		count = min(hdr->ftrace_count, hdr->ftrace_size);
		end = (char *)&hdr->ftrace[count];
		used = end - (char *)hdr;
		printf("trace: copying %08lx bytes of early data from %x to %08lx\n",
		       used, CONFIG_TRACE_EARLY_ADDR,
		       (ulong)map_to_sysmem(buff));
		printf("%lu traced function calls", count);
		if (hdr->ftrace_count > hdr->ftrace_size) {
			printf(" (%lu dropped due to overflow)",
			       hdr->ftrace_count - hdr->ftrace_size);
			hdr->ftrace_count = hdr->ftrace_size;
		}
		puts("\n");
		memcpy(buff, hdr, used);
#else
		puts("trace: already enabled\n");
		return -EALREADY;
#endif
	}
	hdr = (struct trace_hdr *)buff;
	needed = sizeof(*hdr) + func_count * sizeof(uintptr_t);
	if (needed > buff_size) {
		printf("trace: buffer size %zx bytes: at least %zx needed\n",
		       buff_size, needed);
		return -ENOSPC;
	}

	if (was_disabled) {
		memset(hdr, '\0', needed);
		hdr->min_depth = INT_MAX;
	}
	hdr->func_count = func_count;
	hdr->call_accum = (uintptr_t *)(hdr + 1);

	/* Use any remaining space for the timed function trace */
	hdr->ftrace = (struct trace_call *)(buff + needed);
	hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace);
	hdr->depth_limit = CONFIG_TRACE_CALL_DEPTH_LIMIT;

	puts("trace: enabled\n");
	trace_enabled = 1;
	trace_inited = 1;

	return 0;
}

#ifdef CONFIG_TRACE_EARLY
/**
 * trace_early_init() - initialize the tracing system for early tracing
 *
 * Return:	0 if ok, -ENOSPC if not enough memory is available
 */
int notrace trace_early_init(void)
{
	int func_count = get_func_count();
	size_t buff_size = CONFIG_TRACE_EARLY_SIZE;
	size_t needed;

	if (func_count < 0)
		return func_count;
	/* We can ignore additional calls to this function */
	if (trace_enabled)
		return 0;

	hdr = map_sysmem(CONFIG_TRACE_EARLY_ADDR, CONFIG_TRACE_EARLY_SIZE);
	needed = sizeof(*hdr) + func_count * sizeof(uintptr_t);
	if (needed > buff_size) {
		printf("trace: buffer size is %zx bytes, at least %zx needed\n",
		       buff_size, needed);
		return -ENOSPC;
	}

	memset(hdr, '\0', needed);
	hdr->call_accum = (uintptr_t *)(hdr + 1);
	hdr->func_count = func_count;
	hdr->min_depth = INT_MAX;

	/* Use any remaining space for the timed function trace */
	hdr->ftrace = (struct trace_call *)((char *)hdr + needed);
	hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace);
	hdr->depth_limit = CONFIG_TRACE_EARLY_CALL_DEPTH_LIMIT;
	printf("trace: early enable at %08x\n", CONFIG_TRACE_EARLY_ADDR);

	trace_enabled = 1;

	return 0;
}
#endif
