/*
 * Copyright 2016-17 IBM Corp.
 *
 * 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.
 */

#define pr_fmt(fmt) "vas: " fmt

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include "vas.h"

static struct dentry *vas_debugfs;

static char *cop_to_str(int cop)
{
	switch (cop) {
	case VAS_COP_TYPE_FAULT:	return "Fault";
	case VAS_COP_TYPE_842:		return "NX-842 Normal Priority";
	case VAS_COP_TYPE_842_HIPRI:	return "NX-842 High Priority";
	case VAS_COP_TYPE_GZIP:		return "NX-GZIP Normal Priority";
	case VAS_COP_TYPE_GZIP_HIPRI:	return "NX-GZIP High Priority";
	case VAS_COP_TYPE_FTW:		return "Fast Thread-wakeup";
	default:			return "Unknown";
	}
}

static int info_dbg_show(struct seq_file *s, void *private)
{
	struct vas_window *window = s->private;

	mutex_lock(&vas_mutex);

	/* ensure window is not unmapped */
	if (!window->hvwc_map)
		goto unlock;

	seq_printf(s, "Type: %s, %s\n", cop_to_str(window->cop),
					window->tx_win ? "Send" : "Receive");
	seq_printf(s, "Pid : %d\n", window->pid);

unlock:
	mutex_unlock(&vas_mutex);
	return 0;
}

static int info_dbg_open(struct inode *inode, struct file *file)
{
	return single_open(file, info_dbg_show, inode->i_private);
}

static const struct file_operations info_fops = {
	.open		= info_dbg_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static inline void print_reg(struct seq_file *s, struct vas_window *win,
			char *name, u32 reg)
{
	seq_printf(s, "0x%016llx %s\n", read_hvwc_reg(win, name, reg), name);
}

static int hvwc_dbg_show(struct seq_file *s, void *private)
{
	struct vas_window *window = s->private;

	mutex_lock(&vas_mutex);

	/* ensure window is not unmapped */
	if (!window->hvwc_map)
		goto unlock;

	print_reg(s, window, VREG(LPID));
	print_reg(s, window, VREG(PID));
	print_reg(s, window, VREG(XLATE_MSR));
	print_reg(s, window, VREG(XLATE_LPCR));
	print_reg(s, window, VREG(XLATE_CTL));
	print_reg(s, window, VREG(AMR));
	print_reg(s, window, VREG(SEIDR));
	print_reg(s, window, VREG(FAULT_TX_WIN));
	print_reg(s, window, VREG(OSU_INTR_SRC_RA));
	print_reg(s, window, VREG(HV_INTR_SRC_RA));
	print_reg(s, window, VREG(PSWID));
	print_reg(s, window, VREG(LFIFO_BAR));
	print_reg(s, window, VREG(LDATA_STAMP_CTL));
	print_reg(s, window, VREG(LDMA_CACHE_CTL));
	print_reg(s, window, VREG(LRFIFO_PUSH));
	print_reg(s, window, VREG(CURR_MSG_COUNT));
	print_reg(s, window, VREG(LNOTIFY_AFTER_COUNT));
	print_reg(s, window, VREG(LRX_WCRED));
	print_reg(s, window, VREG(LRX_WCRED_ADDER));
	print_reg(s, window, VREG(TX_WCRED));
	print_reg(s, window, VREG(TX_WCRED_ADDER));
	print_reg(s, window, VREG(LFIFO_SIZE));
	print_reg(s, window, VREG(WINCTL));
	print_reg(s, window, VREG(WIN_STATUS));
	print_reg(s, window, VREG(WIN_CTX_CACHING_CTL));
	print_reg(s, window, VREG(TX_RSVD_BUF_COUNT));
	print_reg(s, window, VREG(LRFIFO_WIN_PTR));
	print_reg(s, window, VREG(LNOTIFY_CTL));
	print_reg(s, window, VREG(LNOTIFY_PID));
	print_reg(s, window, VREG(LNOTIFY_LPID));
	print_reg(s, window, VREG(LNOTIFY_TID));
	print_reg(s, window, VREG(LNOTIFY_SCOPE));
	print_reg(s, window, VREG(NX_UTIL_ADDER));
unlock:
	mutex_unlock(&vas_mutex);
	return 0;
}

static int hvwc_dbg_open(struct inode *inode, struct file *file)
{
	return single_open(file, hvwc_dbg_show, inode->i_private);
}

static const struct file_operations hvwc_fops = {
	.open		= hvwc_dbg_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

void vas_window_free_dbgdir(struct vas_window *window)
{
	if (window->dbgdir) {
		debugfs_remove_recursive(window->dbgdir);
		kfree(window->dbgname);
		window->dbgdir = NULL;
		window->dbgname = NULL;
	}
}

void vas_window_init_dbgdir(struct vas_window *window)
{
	struct dentry *f, *d;

	if (!window->vinst->dbgdir)
		return;

	window->dbgname = kzalloc(16, GFP_KERNEL);
	if (!window->dbgname)
		return;

	snprintf(window->dbgname, 16, "w%d", window->winid);

	d = debugfs_create_dir(window->dbgname, window->vinst->dbgdir);
	if (IS_ERR(d))
		goto free_name;

	window->dbgdir = d;

	f = debugfs_create_file("info", 0444, d, window, &info_fops);
	if (IS_ERR(f))
		goto remove_dir;

	f = debugfs_create_file("hvwc", 0444, d, window, &hvwc_fops);
	if (IS_ERR(f))
		goto remove_dir;

	return;

remove_dir:
	debugfs_remove_recursive(window->dbgdir);
	window->dbgdir = NULL;

free_name:
	kfree(window->dbgname);
	window->dbgname = NULL;
}

void vas_instance_init_dbgdir(struct vas_instance *vinst)
{
	struct dentry *d;

	vas_init_dbgdir();
	if (!vas_debugfs)
		return;

	vinst->dbgname = kzalloc(16, GFP_KERNEL);
	if (!vinst->dbgname)
		return;

	snprintf(vinst->dbgname, 16, "v%d", vinst->vas_id);

	d = debugfs_create_dir(vinst->dbgname, vas_debugfs);
	if (IS_ERR(d))
		goto free_name;

	vinst->dbgdir = d;
	return;

free_name:
	kfree(vinst->dbgname);
	vinst->dbgname = NULL;
	vinst->dbgdir = NULL;
}

/*
 * Set up the "root" VAS debugfs dir. Return if we already set it up
 * (or failed to) in an earlier instance of VAS.
 */
void vas_init_dbgdir(void)
{
	static bool first_time = true;

	if (!first_time)
		return;

	first_time = false;
	vas_debugfs = debugfs_create_dir("vas", NULL);
	if (IS_ERR(vas_debugfs))
		vas_debugfs = NULL;
}
