/*
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Exynos-SnapShot debugging framework for Exynos SoC
 *
 * Author: Hosung Kim <Hosung0.kim@samsung.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.
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/ktime.h>
#include <linux/kallsyms.h>
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/pstore_ram.h>
#include <linux/sched/clock.h>
#include <linux/ftrace.h>
#ifdef CONFIG_SEC_EXT
#include <linux/sec_ext.h>
#endif

#include "debug-snapshot-local.h"
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/hardirq.h>
#include <asm/stacktrace.h>
#include <linux/debug-snapshot.h>
#include <linux/kernel_stat.h>
#include <linux/irqnr.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>

/* This defines are for PSTORE */
#define DSS_LOGGER_LEVEL_HEADER		(1)
#define DSS_LOGGER_LEVEL_PREFIX		(2)
#define DSS_LOGGER_LEVEL_TEXT		(3)
#define DSS_LOGGER_LEVEL_MAX		(4)
#define DSS_LOGGER_SKIP_COUNT		(4)
#define DSS_LOGGER_STRING_PAD		(1)
#define DSS_LOGGER_HEADER_SIZE		(69)

#define DSS_LOG_ID_MAIN			(0)
#define DSS_LOG_ID_RADIO		(1)
#define DSS_LOG_ID_EVENTS		(2)
#define DSS_LOG_ID_SYSTEM		(3)
#define DSS_LOG_ID_CRASH		(4)
#define DSS_LOG_ID_KERNEL		(5)

typedef struct __attribute__((__packed__)) {
	uint8_t magic;
	uint16_t len;
	uint16_t uid;
	uint16_t pid;
} dss_pmsg_log_header_t;

typedef struct __attribute__((__packed__)) {
	unsigned char id;
	uint16_t tid;
	int32_t tv_sec;
	int32_t tv_nsec;
} dss_android_log_header_t;

typedef struct dss_logger {
	uint16_t	len;
	uint16_t	id;
	uint16_t	pid;
	uint16_t	tid;
	uint16_t	uid;
	uint16_t	level;
	int32_t		tv_sec;
	int32_t		tv_nsec;
	char		msg;
	char		*buffer;
	void		(*func_hook_logger)(const char*, const char*, size_t);
} __attribute__((__packed__)) dss_logger;

static dss_logger logger;

void register_hook_logger(void (*func)(const char *name, const char *buf, size_t size))
{
	logger.func_hook_logger = func;
	logger.buffer = vmalloc(PAGE_SIZE * 3);

	if (logger.buffer)
		pr_info("debug-snapshot: logger buffer alloc address: 0x%p\n", logger.buffer);
}
EXPORT_SYMBOL(register_hook_logger);

static int dbg_snapshot_combine_pmsg(char *buffer, size_t count, unsigned int level)
{
	char *logbuf = logger.buffer;

	if (!logbuf)
		return -ENOMEM;

	switch (level) {
	case DSS_LOGGER_LEVEL_HEADER:
	{
			struct tm tmBuf;
			u64 tv_kernel;
			unsigned int logbuf_len;
			unsigned long rem_nsec;

			if (logger.id == DSS_LOG_ID_EVENTS)
				break;

			tv_kernel = local_clock();
			rem_nsec = do_div(tv_kernel, 1000000000);
			time_to_tm(logger.tv_sec, 0, &tmBuf);

			logbuf_len = snprintf(logbuf, DSS_LOGGER_HEADER_SIZE,
					"\n[%5lu.%06lu][%d:%16s] %02d-%02d %02d:%02d:%02d.%03d %5d %5d  ",
					(unsigned long)tv_kernel, rem_nsec / 1000,
					raw_smp_processor_id(), current->comm,
					tmBuf.tm_mon + 1, tmBuf.tm_mday,
					tmBuf.tm_hour, tmBuf.tm_min, tmBuf.tm_sec,
					logger.tv_nsec / 1000000, logger.pid, logger.tid);

			logger.func_hook_logger("log_platform", logbuf, logbuf_len - 1);
		}
		break;
	case DSS_LOGGER_LEVEL_PREFIX:
		{
			static const char *kPrioChars = "!.VDIWEFS";
			unsigned char prio = logger.msg;

			if (logger.id == DSS_LOG_ID_EVENTS)
				break;

			logbuf[0] = prio < strlen(kPrioChars) ? kPrioChars[prio] : '?';
			logbuf[1] = ' ';

			logger.func_hook_logger("log_platform", logbuf, DSS_LOGGER_LEVEL_PREFIX);
		}
		break;
	case DSS_LOGGER_LEVEL_TEXT:
		{
			char *eatnl = buffer + count - DSS_LOGGER_STRING_PAD;

			if (logger.id == DSS_LOG_ID_EVENTS)
				break;
			if (count == DSS_LOGGER_SKIP_COUNT && *eatnl != '\0')
				break;

			logger.func_hook_logger("log_platform", buffer, count - 1);
#ifdef CONFIG_SEC_EXT
			if (count > 1 && strncmp(buffer, "!@", 2) == 0) {
				/* To prevent potential buffer overrun
				 * put a null at the end of the buffer if required
				 */
				buffer[count - 1] = '\0';
				pr_info("%s\n", buffer);
#ifdef CONFIG_SEC_BOOTSTAT
				if (count > 5 && strncmp(buffer, "!@Boot", 6) == 0)
					sec_bootstat_add(buffer);
#endif /* CONFIG_SEC_BOOTSTAT */

			}
#endif /* CONFIG_SEC_EXT */
		}
		break;
	default:
		break;
	}
	return 0;
}

int dbg_snapshot_hook_pmsg(char *buffer, size_t count)
{
	dss_android_log_header_t header;
	dss_pmsg_log_header_t pmsg_header;

	if (!logger.buffer)
		return -ENOMEM;

	switch (count) {
	case sizeof(pmsg_header):
		memcpy((void *)&pmsg_header, buffer, count);
		if (pmsg_header.magic != 'l') {
			dbg_snapshot_combine_pmsg(buffer, count, DSS_LOGGER_LEVEL_TEXT);
		} else {
			/* save logger data */
			logger.pid = pmsg_header.pid;
			logger.uid = pmsg_header.uid;
			logger.len = pmsg_header.len;
		}
		break;
	case sizeof(header):
		/* save logger data */
		memcpy((void *)&header, buffer, count);
		logger.id = header.id;
		logger.tid = header.tid;
		logger.tv_sec = header.tv_sec;
		logger.tv_nsec  = header.tv_nsec;
		if (logger.id > 7) {
			/* write string */
			dbg_snapshot_combine_pmsg(buffer, count, DSS_LOGGER_LEVEL_TEXT);
		} else {
			/* write header */
			dbg_snapshot_combine_pmsg(buffer, count, DSS_LOGGER_LEVEL_HEADER);
		}
		break;
	case sizeof(unsigned char):
		logger.msg = buffer[0];
		/* write char for prefix */
		dbg_snapshot_combine_pmsg(buffer, count, DSS_LOGGER_LEVEL_PREFIX);
		break;
	default:
		/* write string */
		dbg_snapshot_combine_pmsg(buffer, count, DSS_LOGGER_LEVEL_TEXT);
		break;
	}

	return 0;
}
EXPORT_SYMBOL(dbg_snapshot_hook_pmsg);

/*
 *  To support pstore/pmsg/pstore_ram, following is implementation for debug-snapshot
 *  dss_ramoops platform_device is used by pstore fs.
 */

static struct ramoops_platform_data dss_ramoops_data = {
	.record_size	= SZ_4K,
	.pmsg_size	= SZ_4K,
	.dump_oops	= 1,
};

static struct platform_device dss_ramoops = {
	.name = "ramoops",
	.dev = {
		.platform_data = &dss_ramoops_data,
	},
};

static int __init dss_pstore_init(void)
{
	if (dbg_snapshot_get_enable("log_pstore")) {
		dss_ramoops_data.mem_size = dbg_snapshot_get_item_size("log_pstore");
		dss_ramoops_data.mem_address = dbg_snapshot_get_item_paddr("log_pstore");
		dss_ramoops_data.pmsg_size = dss_ramoops_data.mem_size / 2;
		dss_ramoops_data.record_size = dss_ramoops_data.mem_size / 2;
	}
	return platform_device_register(&dss_ramoops);
}

static void __exit dss_pstore_exit(void)
{
	platform_device_unregister(&dss_ramoops);
}
module_init(dss_pstore_init);
module_exit(dss_pstore_exit);

MODULE_DESCRIPTION("Exynos Snapshot pstore module");
MODULE_LICENSE("GPL");
