/*
 * Copyright (c) 2011 The Chromium OS Authors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <trace.h>
#include <asm/io.h>

static int get_args(int argc, char * const argv[], char **buff,
		    size_t *buff_ptr, size_t *buff_size)
{
	if (argc < 2)
		return -1;
	if (argc < 4) {
		*buff_size = getenv_ulong("profsize", 16, 0);
		*buff = map_sysmem(getenv_ulong("profbase", 16, 0),
				   *buff_size);
		*buff_ptr = getenv_ulong("profoffset", 16, 0);
	} else {
		*buff_size = simple_strtoul(argv[3], NULL, 16);
		*buff = map_sysmem(simple_strtoul(argv[2], NULL, 16),
				   *buff_size);
		*buff_ptr = 0;
	};
	return 0;
}

static int create_func_list(int argc, char * const argv[])
{
	size_t buff_size, avail, buff_ptr, used;
	unsigned int needed;
	char *buff;
	int err;

	if (get_args(argc, argv, &buff, &buff_ptr, &buff_size))
		return -1;

	avail = buff_size - buff_ptr;
	err = trace_list_functions(buff + buff_ptr, avail, &needed);
	if (err)
		printf("Error: truncated (%#x bytes needed)\n", needed);
	used = min(avail, needed);
	printf("Function trace dumped to %08lx, size %#zx\n",
	       (ulong)map_to_sysmem(buff + buff_ptr), used);
	setenv_hex("profbase", map_to_sysmem(buff));
	setenv_hex("profsize", buff_size);
	setenv_hex("profoffset", buff_ptr + used);

	return 0;
}

static int create_call_list(int argc, char * const argv[])
{
	size_t buff_size, avail, buff_ptr, used;
	unsigned int needed;
	char *buff;
	int err;

	if (get_args(argc, argv, &buff, &buff_ptr, &buff_size))
		return -1;

	avail = buff_size - buff_ptr;
	err = trace_list_calls(buff + buff_ptr, avail, &needed);
	if (err)
		printf("Error: truncated (%#x bytes needed)\n", needed);
	used = min(avail, needed);
	printf("Call list dumped to %08lx, size %#zx\n",
	       (ulong)map_to_sysmem(buff + buff_ptr), used);

	setenv_hex("profbase", map_to_sysmem(buff));
	setenv_hex("profsize", buff_size);
	setenv_hex("profoffset", buff_ptr + used);

	return 0;
}

int do_trace(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const char *cmd = argc < 2 ? NULL : argv[1];

	if (!cmd)
		return cmd_usage(cmdtp);
	switch (*cmd) {
	case 'p':
		trace_set_enabled(0);
		break;
	case 'c':
		if (create_call_list(argc, argv))
			return cmd_usage(cmdtp);
		break;
	case 'r':
		trace_set_enabled(1);
		break;
	case 'f':
		if (create_func_list(argc, argv))
			return cmd_usage(cmdtp);
		break;
	case 's':
		trace_print_stats();
		break;
	default:
		return CMD_RET_USAGE;
	}

	return 0;
}

U_BOOT_CMD(
	trace,	4,	1,	do_trace,
	"trace utility commands",
	"stats                        - display tracing statistics\n"
	"trace pause                        - pause tracing\n"
	"trace resume                       - resume tracing\n"
	"trace funclist [<addr> <size>]     - dump function list into buffer\n"
	"trace calls  [<addr> <size>]       "
		"- dump function call trace into buffer"
);
