/*
 * (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

#ifdef CONFIG_POST

#define POST_MAX_NUMBER		32

#define BOOTMODE_MAGIC	0xDEAD0000

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

	if (bootmode == 0) {
		bootmode = POST_POWERON;
	} else if (bootmode == POST_POWERON) {
		bootmode = POST_POWERNORMAL;
	} else {
		return;
	}

	post_word_store (BOOTMODE_MAGIC | bootmode);
}

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 & 0xFF;

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

	return bootmode;
}

void post_bootmode_clear (void)
{
	post_word_store (0);
}

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_POWERNORMAL, POST_POWERFAIL };
	char *var[] = { "post_poweron", "post_normal", "post_shutdown" };
	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;
		}
	}
}

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

			post_log ("POST %s ", test->cmd);
		}

		if ((*test->test) (flags) != 0)
			post_log ("FAILED\n");
		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 (post_bootmode_get (&last) & POST_POWERTEST) {
			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++) {
					post_run_single (post_list + i,
							 test_flags[i],
							 flags, i);
				}
			}
		} else {
			for (i = 0; i < post_list_size; i++) {
				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
	logbuff_log (printbuffer);
#else
	/* Send to the stdout file */
	puts (printbuffer);
#endif

	return 0;
}

void post_reloc (void)
{
	DECLARE_GLOBAL_DATA_PTR;

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

#endif /* CONFIG_POST */
