/*
 * (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 <console.h>
#include <watchdog.h>
#include <post.h>

#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("post/post.c: post_time_ms seems not to be implemented\n");
	}

	return res;
}

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;
}

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)<<16;
}

static void post_log_mark_succ ( unsigned long testid )
{
	gd->post_log_word |= 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<<16)) {
			post_log ("POST %s ", post_list[j].cmd);
			if (gd->post_log_word & 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);
}

static void post_get_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 = sizeof (var) / sizeof (var[0]);
	char list[128];			/* long enough for POST list */
	char *name;
	char *s;
	int last;
	int i, j;

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

	for (i = 0; i < varnum; i++) {
		if (getenv_r (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;
		}
	}

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

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);
		}

		if (test_flags & POST_PREREL) {
			if ((*test->test) (flags) == 0)
				post_log_mark_succ ( test->testid );
			else {
				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);
			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");
		}

		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) {
			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[CFG_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;
}

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();
		}
	}
}


/*
 * 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)
{
#ifdef CONFIG_PPC
	return (unsigned long)(get_ticks () / (get_tbclk () / CFG_HZ)) - base;
#else
#warning "Not implemented yet"
	return 0; /* Not implemented yet */
#endif
}
