/*
 * (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_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) {
			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;
}

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 () / CONFIG_SYS_HZ)) - base;
#else
#warning "Not implemented yet"
	return 0; /* Not implemented yet */
#endif
}
