/*
 * Crash information logger
 * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
 *
 * Based on ramoops.c
 *   Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/bootmem.h>
#include <linux/debugfs.h>
#include <linux/crashlog.h>
#include <linux/kmsg_dump.h>
#include <linux/module.h>
#include <linux/pfn.h>
#include <asm/io.h>

#define CRASHLOG_PAGES	4
#define CRASHLOG_SIZE	(CRASHLOG_PAGES * PAGE_SIZE)
#define CRASHLOG_MAGIC	0xa1eedead

/*
 * Start the log at 1M before the end of RAM, as some boot loaders like
 * to use the end of the RAM for stack usage and other things
 * If this fails, fall back to using the last part.
 */
#define CRASHLOG_OFFSET	(1024 * 1024)

struct crashlog_data {
	u32 magic;
	u32 len;
	u8 data[];
};

static struct debugfs_blob_wrapper crashlog_blob;
static unsigned long crashlog_addr = 0;
static struct crashlog_data *crashlog_buf;
static struct kmsg_dumper dump;
static bool first = true;

extern struct list_head *crashlog_modules;

void __init crashlog_init_mem(bootmem_data_t *bdata)
{
	unsigned long addr;

	if (crashlog_addr)
		return;

	addr = PFN_PHYS(bdata->node_low_pfn) - CRASHLOG_OFFSET;
	if (reserve_bootmem(addr, CRASHLOG_SIZE, BOOTMEM_EXCLUSIVE) < 0) {
		printk("Crashlog failed to allocate RAM at address 0x%lx\n", addr);
		bdata->node_low_pfn -= CRASHLOG_PAGES;
		addr = PFN_PHYS(bdata->node_low_pfn);
	}
	crashlog_addr = addr;
}

static void __init crashlog_copy(void)
{
	if (crashlog_buf->magic != CRASHLOG_MAGIC)
		return;

	if (!crashlog_buf->len || crashlog_buf->len >
	    CRASHLOG_SIZE - sizeof(*crashlog_buf))
		return;

	crashlog_blob.size = crashlog_buf->len;
	crashlog_blob.data = kmemdup(crashlog_buf->data,
		crashlog_buf->len, GFP_KERNEL);

	debugfs_create_blob("crashlog", 0700, NULL, &crashlog_blob);
}

static int get_maxlen(void)
{
	return CRASHLOG_SIZE - sizeof(*crashlog_buf) - crashlog_buf->len;
}

static void crashlog_printf(const char *fmt, ...)
{
	va_list args;
	int len = get_maxlen();

	if (!len)
		return;

	va_start(args, fmt);
	crashlog_buf->len += vsnprintf(
		&crashlog_buf->data[crashlog_buf->len],
		len, fmt, args);
	va_end(args);
}

static void crashlog_do_dump(struct kmsg_dumper *dumper,
		enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
		const char *s2, unsigned long l2)
{
	unsigned long s1_start, s2_start;
	unsigned long l1_cpy, l2_cpy;
	struct timeval tv;
	struct module *m;
	char *buf;
	int len;

	if (!first)
		crashlog_printf("\n===================================\n");

	do_gettimeofday(&tv);
	crashlog_printf("Time: %lu.%lu\n",
		(long)tv.tv_sec, (long)tv.tv_usec);

	if (first) {
		crashlog_printf("Modules:");
		list_for_each_entry(m, crashlog_modules, list) {
			crashlog_printf("\t%s@%p+%x", m->name,
			m->module_core, m->core_size,
			m->module_init, m->init_size);
		}
		crashlog_printf("\n");
		first = false;
	}

	buf = (char *)&crashlog_buf->data[crashlog_buf->len];
	len = get_maxlen();

	l2_cpy = min(l2, (unsigned long)len);
	l1_cpy = min(l1, (unsigned long)len - l2_cpy);

	s2_start = l2 - l2_cpy;
	s1_start = l1 - l1_cpy;

	memcpy(buf, s1 + s1_start, l1_cpy);
	memcpy(buf + l1_cpy, s2 + s2_start, l2_cpy);
	crashlog_buf->len += l1_cpy + l2_cpy;
}


int __init crashlog_init_fs(void)
{
	if (!crashlog_addr)
		return -ENOMEM;

	crashlog_buf = ioremap(crashlog_addr, CRASHLOG_SIZE);

	crashlog_copy();

	crashlog_buf->magic = CRASHLOG_MAGIC;
	crashlog_buf->len = 0;

	dump.dump = crashlog_do_dump;
	kmsg_dump_register(&dump);

	return 0;
}
module_init(crashlog_init_fs);
