/*
 * (C) Copyright 2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 <stdio_dev.h>
#include <watchdog.h>
#include <post.h>

#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
#include <asm/gpio.h>
#endif

#ifdef CONFIG_LOGBUFFER
#include <logbuff.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

#define POST_MAX_NUMBER		32

#define BOOTMODE_MAGIC	0xDEAD0000

int post_init_f(void)
{
	int res = 0;
	unsigned int i;

	for (i = 0; i < post_list_size; i++) {
		struct post_test *test = post_list + i;

		if (test->init_f && test->init_f()) {
			res = -1;
		}
	}

	gd->post_init_f_time = post_time_ms(0);
	if (!gd->post_init_f_time)
		printf("%s: post_time_ms not implemented\n", __FILE__);

	return res;
}

/*
 * Supply a default implementation for post_hotkeys_pressed() for boards
 * without hotkey support. We always return 0 here, so that the
 * long-running tests won't be started.
 *
 * Boards with hotkey support can override this weak default function
 * by defining one in their board specific code.
 */
int __post_hotkeys_pressed(void)
{
#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
	int ret;
	unsigned gpio = CONFIG_SYS_POST_HOTKEYS_GPIO;

	ret = gpio_request(gpio, "hotkeys");
	if (ret) {
		printf("POST: gpio hotkey request failed\n");
		return 0;
	}

	gpio_direction_input(gpio);
	ret = gpio_get_value(gpio);
	gpio_free(gpio);

	return ret;
#endif

	return 0;	/* No hotkeys supported */
}
int post_hotkeys_pressed(void)
	__attribute__((weak, alias("__post_hotkeys_pressed")));


void post_bootmode_init(void)
{
	int bootmode = post_bootmode_get(0);
	int newword;

	if (post_hotkeys_pressed() && !(bootmode & POST_POWERTEST))
		newword = BOOTMODE_MAGIC | POST_SLOWTEST;
	else if (bootmode == 0)
		newword = BOOTMODE_MAGIC | POST_POWERON;
	else if (bootmode == POST_POWERON || bootmode == POST_SLOWTEST)
		newword = BOOTMODE_MAGIC | POST_NORMAL;
	else
		/* Use old value */
		newword = post_word_load () & ~POST_COLDBOOT;

	if (bootmode == 0)
		/* We are booting after power-on */
		newword |= POST_COLDBOOT;

	post_word_store(newword);

	/* Reset activity record */
	gd->post_log_word = 0;
	gd->post_log_res = 0;
}

int post_bootmode_get(unsigned int *last_test)
{
	unsigned long word = post_word_load();
	int bootmode;

	if ((word & 0xFFFF0000) != BOOTMODE_MAGIC)
		return 0;

	bootmode = word & 0x7F;

	if (last_test && (bootmode & POST_POWERTEST))
		*last_test = (word >> 8) & 0xFF;

	return bootmode;
}

/* POST tests run before relocation only mark status bits .... */
static void post_log_mark_start(unsigned long testid)
{
	gd->post_log_word |= testid;
}

static void post_log_mark_succ(unsigned long testid)
{
	gd->post_log_res |= testid;
}

/* ... and the messages are output once we are relocated */
void post_output_backlog(void)
{
	int j;

	for (j = 0; j < post_list_size; j++) {
		if (gd->post_log_word & (post_list[j].testid)) {
			post_log ("POST %s ", post_list[j].cmd);
			if (gd->post_log_res & post_list[j].testid)
				post_log ("PASSED\n");
			else {
				post_log("FAILED\n");
				show_boot_progress(-31);
			}
		}
	}
}

static void post_bootmode_test_on(unsigned int last_test)
{
	unsigned long word = post_word_load();

	word |= POST_POWERTEST;

	word |= (last_test & 0xFF) << 8;

	post_word_store(word);
}

static void post_bootmode_test_off(void)
{
	unsigned long word = post_word_load();

	word &= ~POST_POWERTEST;

	post_word_store(word);
}

#ifndef CONFIG_POST_SKIP_ENV_FLAGS
static void post_get_env_flags(int *test_flags)
{
	int  flag[] = {  POST_POWERON,   POST_NORMAL,   POST_SLOWTEST,
			 POST_CRITICAL };
	char *var[] = { "post_poweron", "post_normal", "post_slowtest",
			"post_critical" };
	int varnum = ARRAY_SIZE(var);
	char list[128];			/* long enough for POST list */
	char *name;
	char *s;
	int last;
	int i, j;

	for (i = 0; i < varnum; i++) {
		if (getenv_f(var[i], list, sizeof (list)) <= 0)
			continue;

		for (j = 0; j < post_list_size; j++) {
			test_flags[j] &= ~flag[i];
		}

		last = 0;
		name = list;
		while (!last) {
			while (*name && *name == ' ')
				name++;
			if (*name == 0)
				break;
			s = name + 1;
			while (*s && *s != ' ')
				s++;
			if (*s == 0)
				last = 1;
			else
				*s = 0;

			for (j = 0; j < post_list_size; j++) {
				if (strcmp (post_list[j].cmd, name) == 0) {
					test_flags[j] |= flag[i];
					break;
				}
			}

			if (j == post_list_size)
				printf ("No such test: %s\n", name);

			name = s + 1;
		}
	}
}
#endif

static void post_get_flags(int *test_flags)
{
	int j;

	for (j = 0; j < post_list_size; j++)
		test_flags[j] = post_list[j].flags;

#ifndef CONFIG_POST_SKIP_ENV_FLAGS
	post_get_env_flags(test_flags);
#endif

	for (j = 0; j < post_list_size; j++)
		if (test_flags[j] & POST_POWERON)
			test_flags[j] |= POST_SLOWTEST;
}

void __show_post_progress(unsigned int test_num, int before, int result)
{
}
void show_post_progress(unsigned int, int, int)
			__attribute__((weak, alias("__show_post_progress")));

static int post_run_single(struct post_test *test,
				int test_flags, int flags, unsigned int i)
{
	if ((flags & test_flags & POST_ALWAYS) &&
		(flags & test_flags & POST_MEM)) {
		WATCHDOG_RESET ();

		if (!(flags & POST_REBOOT)) {
			if ((test_flags & POST_REBOOT) &&
				!(flags & POST_MANUAL)) {
				post_bootmode_test_on(
					(gd->flags & GD_FLG_POSTFAIL) ?
						POST_FAIL_SAVE | i : i);
			}

			if (test_flags & POST_PREREL)
				post_log_mark_start(test->testid);
			else
				post_log("POST %s ", test->cmd);
		}

		show_post_progress(i, POST_BEFORE, POST_FAILED);

		if (test_flags & POST_PREREL) {
			if ((*test->test) (flags) == 0) {
				post_log_mark_succ(test->testid);
				show_post_progress(i, POST_AFTER, POST_PASSED);
			}
			else {
				show_post_progress(i, POST_AFTER, POST_FAILED);
				if (test_flags & POST_CRITICAL)
					gd->flags |= GD_FLG_POSTFAIL;
				if (test_flags & POST_STOP)
					gd->flags |= GD_FLG_POSTSTOP;
			}
		} else {
			if ((*test->test)(flags) != 0) {
				post_log("FAILED\n");
				show_boot_progress(-32);
				show_post_progress(i, POST_AFTER, POST_FAILED);
				if (test_flags & POST_CRITICAL)
					gd->flags |= GD_FLG_POSTFAIL;
				if (test_flags & POST_STOP)
					gd->flags |= GD_FLG_POSTSTOP;
			} else {
				post_log("PASSED\n");
				show_post_progress(i, POST_AFTER, POST_PASSED);
			}
		}

		if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) {
			post_bootmode_test_off();
		}

		return 0;
	} else {
		return -1;
	}
}

int post_run (char *name, int flags)
{
	unsigned int i;
	int test_flags[POST_MAX_NUMBER];

	post_get_flags(test_flags);

	if (name == NULL) {
		unsigned int last;

		if (gd->flags & GD_FLG_POSTSTOP)
			return 0;

		if (post_bootmode_get(&last) & POST_POWERTEST) {
			if (last & POST_FAIL_SAVE) {
				last &= ~POST_FAIL_SAVE;
				gd->flags |= GD_FLG_POSTFAIL;
			}
			if (last < post_list_size &&
				(flags & test_flags[last] & POST_ALWAYS) &&
				(flags & test_flags[last] & POST_MEM)) {

				post_run_single(post_list + last,
						 test_flags[last],
						 flags | POST_REBOOT, last);

				for (i = last + 1; i < post_list_size; i++) {
					if (gd->flags & GD_FLG_POSTSTOP)
						break;
					post_run_single(post_list + i,
							 test_flags[i],
							 flags, i);
				}
			}
		} else {
			for (i = 0; i < post_list_size; i++) {
				if (gd->flags & GD_FLG_POSTSTOP)
					break;
				post_run_single(post_list + i,
						 test_flags[i],
						 flags, i);
			}
		}

		return 0;
	} else {
		for (i = 0; i < post_list_size; i++) {
			if (strcmp (post_list[i].cmd, name) == 0)
				break;
		}

		if (i < post_list_size) {
			WATCHDOG_RESET();
			return post_run_single(post_list + i,
						test_flags[i],
						flags, i);
		} else {
			return -1;
		}
	}
}

static int post_info_single(struct post_test *test, int full)
{
	if (test->flags & POST_MANUAL) {
		if (full)
			printf("%s - %s\n"
				"  %s\n", test->cmd, test->name, test->desc);
		else
			printf("  %-15s - %s\n", test->cmd, test->name);

		return 0;
	} else {
		return -1;
	}
}

int post_info (char *name)
{
	unsigned int i;

	if (name == NULL) {
		for (i = 0; i < post_list_size; i++)
			post_info_single(post_list + i, 0);

		return 0;
	} else {
		for (i = 0; i < post_list_size; i++) {
			if (strcmp (post_list[i].cmd, name) == 0)
				break;
		}

		if (i < post_list_size) {
			return post_info_single(post_list + i, 1);
		} else {
			return -1;
		}
	}
}

int post_log(char *format, ...)
{
	va_list args;
	uint i;
	char printbuffer[CONFIG_SYS_PBSIZE];

	va_start (args, format);

	/* For this to work, printbuffer must be larger than
	 * anything we ever want to print.
	 */
	i = vsprintf (printbuffer, format, args);
	va_end (args);

#ifdef CONFIG_LOGBUFFER
	/* Send to the logbuffer */
	logbuff_log(printbuffer);
#else
	/* Send to the stdout file */
	puts(printbuffer);
#endif

	return 0;
}

#ifdef CONFIG_NEEDS_MANUAL_RELOC
void post_reloc(void)
{
	unsigned int i;

	/*
	 * We have to relocate the test table manually
	 */
	for (i = 0; i < post_list_size; i++) {
		ulong addr;
		struct post_test *test = post_list + i;

		if (test->name) {
			addr = (ulong) (test->name) + gd->reloc_off;
			test->name = (char *)addr;
		}

		if (test->cmd) {
			addr = (ulong) (test->cmd) + gd->reloc_off;
			test->cmd = (char *)addr;
		}

		if (test->desc) {
			addr = (ulong) (test->desc) + gd->reloc_off;
			test->desc = (char *)addr;
		}

		if (test->test) {
			addr = (ulong) (test->test) + gd->reloc_off;
			test->test = (int (*)(int flags)) addr;
		}

		if (test->init_f) {
			addr = (ulong) (test->init_f) + gd->reloc_off;
			test->init_f = (int (*)(void)) addr;
		}

		if (test->reloc) {
			addr = (ulong) (test->reloc) + gd->reloc_off;
			test->reloc = (void (*)(void)) addr;

			test->reloc();
		}
	}
}
#endif


/*
 * Some tests (e.g. SYSMON) need the time when post_init_f started,
 * but we cannot use get_timer() at this point.
 *
 * On PowerPC we implement it using the timebase register.
 */
unsigned long post_time_ms(unsigned long base)
{
#if defined(CONFIG_PPC) || defined(CONFIG_ARM)
	return (unsigned long)(get_ticks() / (get_tbclk() / CONFIG_SYS_HZ))
		- base;
#else
#warning "Not implemented yet"
	return 0; /* Not implemented yet */
#endif
}
