/*
 * (C) Copyright 2002-2007
 * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
 *
 * Code used from linux/kernel/printk.c
 * Copyright (C) 1991, 1992  Linus Torvalds
 *
 * 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
 *
 * Comments:
 *
 * After relocating the code, the environment variable "loglevel" is
 * copied to console_loglevel.  The functionality is similar to the
 * handling in the Linux kernel, i.e. messages logged with a priority
 * less than console_loglevel are also output to stdout.
 *
 * If you want messages with the default level (e.g. POST messages) to
 * appear on stdout also, make sure the environment variable
 * "loglevel" is set at boot time to a number higher than
 * default_message_loglevel below.
 */

/*
 * Logbuffer handling routines
 */

#include <common.h>
#include <command.h>
#include <devices.h>
#include <post.h>
#include <logbuff.h>

DECLARE_GLOBAL_DATA_PTR;

/* Local prototypes */
static void logbuff_putc (const char c);
static void logbuff_puts (const char *s);
static int logbuff_printk(const char *line);

static char buf[1024];

/* This combination will not print messages with the default loglevel */
static unsigned console_loglevel = 3;
static unsigned default_message_loglevel = 4;
static unsigned log_version = 1;
#ifdef CONFIG_ALT_LB_ADDR
static volatile logbuff_t *log;
#else
static logbuff_t *log;
#endif
static char *lbuf;

void logbuff_init_ptrs (void)
{
	unsigned long tag, post_word;
	char *s;

#ifdef CONFIG_ALT_LB_ADDR
	log = (logbuff_t *)CONFIG_ALT_LH_ADDR;
	lbuf = (char *)CONFIG_ALT_LB_ADDR;
#else
	log = (logbuff_t *)(gd->bd->bi_memsize-LOGBUFF_LEN) - 1;
	lbuf = (char *)log->buf;
#endif

	/* Set up log version */
	if ((s = getenv ("logversion")) != NULL)
		log_version = (int)simple_strtoul (s, NULL, 10);

	if (log_version == 2)
		tag = log->v2.tag;
	else
		tag = log->v1.tag;
	post_word = post_word_load();
#ifdef CONFIG_POST
	/* The post routines have setup the word so we can simply test it */
	if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) {
		logbuff_reset ();
	}
#else
	/* No post routines, so we do our own checking                    */
	if (tag != LOGBUFF_MAGIC || post_word != LOGBUFF_MAGIC) {
		logbuff_reset ();
		post_word_store (LOGBUFF_MAGIC);
	}
#endif
	if (log_version == 2 && (long)log->v2.start > (long)log->v2.con)
		log->v2.start = log->v2.con;

	/* Initialize default loglevel if present */
	if ((s = getenv ("loglevel")) != NULL)
		console_loglevel = (int)simple_strtoul (s, NULL, 10);

	gd->post_log_word |= LOGBUFF_INITIALIZED;
}

void logbuff_reset (void)
{
#ifndef CONFIG_ALT_LB_ADDR
	memset (log, 0, sizeof (logbuff_t));
#endif
	if (log_version == 2) {
		log->v2.tag = LOGBUFF_MAGIC;
#ifdef CONFIG_ALT_LB_ADDR
		log->v2.start = 0;
		log->v2.con = 0;
		log->v2.end = 0;
		log->v2.chars = 0;
#endif
	} else {
		log->v1.tag = LOGBUFF_MAGIC;
#ifdef CONFIG_ALT_LB_ADDR
		log->v1.dummy = 0;
		log->v1.start = 0;
		log->v1.size = 0;
		log->v1.chars = 0;
#endif
	}
}

int drv_logbuff_init (void)
{
	device_t logdev;
	int rc;

	/* Device initialization */
	memset (&logdev, 0, sizeof (logdev));

	strcpy (logdev.name, "logbuff");
	logdev.ext   = 0;			/* No extensions */
	logdev.flags = DEV_FLAGS_OUTPUT;	/* Output only */
	logdev.putc  = logbuff_putc;		/* 'putc' function */
	logdev.puts  = logbuff_puts;		/* 'puts' function */

	rc = device_register (&logdev);

	return (rc == 0) ? 1 : rc;
}

static void logbuff_putc (const char c)
{
	char buf[2];
	buf[0] = c;
	buf[1] = '\0';
	logbuff_printk (buf);
}

static void logbuff_puts (const char *s)
{
	logbuff_printk (s);
}

void logbuff_log(char *msg)
{
	if ((gd->post_log_word & LOGBUFF_INITIALIZED)) {
		logbuff_printk (msg);
	} else {
		/* Can happen only for pre-relocated errors as logging */
		/* at that stage should be disabled                    */
		puts (msg);
	}
}

/*
 * Subroutine:  do_log
 *
 * Description: Handler for 'log' command..
 *
 * Inputs:	argv[1] contains the subcommand
 *
 * Return:      None
 *
 */
int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	char *s;
	unsigned long i, start, size;

	if (strcmp(argv[1],"append") == 0) {
		/* Log concatenation of all arguments separated by spaces */
		for (i=2; i<argc; i++) {
			logbuff_printk (argv[i]);
			logbuff_putc ((i<argc-1) ? ' ' : '\n');
		}
		return 0;
	}

	switch (argc) {

	case 2:
		if (strcmp(argv[1],"show") == 0) {
			if (log_version == 2) {
				start = log->v2.start;
				size = log->v2.end - log->v2.start;
			}
			else {
				start = log->v1.start;
				size = log->v1.size;
			}
			for (i=0; i < (size&LOGBUFF_MASK); i++) {
				s = lbuf+((start+i)&LOGBUFF_MASK);
				putc (*s);
			}
			return 0;
		} else if (strcmp(argv[1],"reset") == 0) {
			logbuff_reset ();
			return 0;
		} else if (strcmp(argv[1],"info") == 0) {
			printf ("Logbuffer   at  %08lx\n", (unsigned long)lbuf);
			if (log_version == 2) {
				printf ("log_start    =  %08lx\n", log->v2.start);
				printf ("log_end      =  %08lx\n", log->v2.end);
				printf ("logged_chars =  %08lx\n", log->v2.chars);
			}
			else {
				printf ("log_start    =  %08lx\n", log->v1.start);
				printf ("log_size     =  %08lx\n", log->v1.size);
				printf ("logged_chars =  %08lx\n", log->v1.chars);
			}
			return 0;
		}
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;

	default:
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
}

U_BOOT_CMD(
	log,     255,	1,	do_log,
	"log     - manipulate logbuffer\n",
	"info   - show pointer details\n"
	"log reset  - clear contents\n"
	"log show   - show contents\n"
	"log append <msg> - append <msg> to the logbuffer\n"
);

static int logbuff_printk(const char *line)
{
	int i;
	char *msg, *p, *buf_end;
	int line_feed;
	static signed char msg_level = -1;

	strcpy (buf + 3, line);
	i = strlen (line);
	buf_end = buf + 3 + i;
	for (p = buf + 3; p < buf_end; p++) {
		msg = p;
		if (msg_level < 0) {
			if (
				p[0] != '<' ||
				p[1] < '0' ||
				p[1] > '7' ||
				p[2] != '>'
			) {
				p -= 3;
				p[0] = '<';
				p[1] = default_message_loglevel + '0';
				p[2] = '>';
			} else
				msg += 3;
			msg_level = p[1] - '0';
		}
		line_feed = 0;
		for (; p < buf_end; p++) {
			if (log_version == 2) {
				lbuf[log->v2.end & LOGBUFF_MASK] = *p;
				log->v2.end++;
				if (log->v2.end - log->v2.start > LOGBUFF_LEN)
					log->v2.start++;
				log->v2.chars++;
			}
			else {
				lbuf[(log->v1.start + log->v1.size) &
					 LOGBUFF_MASK] = *p;
				if (log->v1.size < LOGBUFF_LEN)
					log->v1.size++;
				else
					log->v1.start++;
				log->v1.chars++;
			}
			if (*p == '\n') {
				line_feed = 1;
				break;
			}
		}
		if (msg_level < console_loglevel) {
			printf("%s", msg);
		}
		if (line_feed)
			msg_level = -1;
	}
	return i;
}
