// SPDX-License-Identifier: GPL-2.0
/*
 * KGDB NMI serial console
 *
 * Copyright 2010 Google, Inc.
 *		  Arve Hjønnevåg <arve@android.com>
 *		  Colin Cross <ccross@android.com>
 * Copyright 2012 Linaro Ltd.
 *		  Anton Vorontsov <anton.vorontsov@linaro.org>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/atomic.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/tick.h>
#include <linux/kfifo.h>
#include <linux/kgdb.h>
#include <linux/kdb.h>

static int kgdb_nmi_knock = 1;
module_param_named(knock, kgdb_nmi_knock, int, 0600);
MODULE_PARM_DESC(knock, "if set to 1 (default), the special '$3#33' command " \
			"must be used to enter the debugger; when set to 0, " \
			"hitting return key is enough to enter the debugger; " \
			"when set to -1, the debugger is entered immediately " \
			"upon NMI");

static char *kgdb_nmi_magic = "$3#33";
module_param_named(magic, kgdb_nmi_magic, charp, 0600);
MODULE_PARM_DESC(magic, "magic sequence to enter NMI debugger (default $3#33)");

static atomic_t kgdb_nmi_num_readers = ATOMIC_INIT(0);

static int kgdb_nmi_console_setup(struct console *co, char *options)
{
	arch_kgdb_ops.enable_nmi(1);

	/* The NMI console uses the dbg_io_ops to issue console messages. To
	 * avoid duplicate messages during kdb sessions we must inform kdb's
	 * I/O utilities that messages sent to the console will automatically
	 * be displayed on the dbg_io.
	 */
	dbg_io_ops->cons = co;

	return 0;
}

static void kgdb_nmi_console_write(struct console *co, const char *s, uint c)
{
	int i;

	for (i = 0; i < c; i++)
		dbg_io_ops->write_char(s[i]);
}

static struct tty_driver *kgdb_nmi_tty_driver;

static struct tty_driver *kgdb_nmi_console_device(struct console *co, int *idx)
{
	*idx = co->index;
	return kgdb_nmi_tty_driver;
}

static struct console kgdb_nmi_console = {
	.name	= "ttyNMI",
	.setup  = kgdb_nmi_console_setup,
	.write	= kgdb_nmi_console_write,
	.device	= kgdb_nmi_console_device,
	.flags	= CON_PRINTBUFFER | CON_ANYTIME,
	.index	= -1,
};

/*
 * This is usually the maximum rate on debug ports. We make fifo large enough
 * to make copy-pasting to the terminal usable.
 */
#define KGDB_NMI_BAUD		115200
#define KGDB_NMI_FIFO_SIZE	roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ)

struct kgdb_nmi_tty_priv {
	struct tty_port port;
	struct timer_list timer;
	STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo;
};

static struct tty_port *kgdb_nmi_port;

static void kgdb_tty_recv(int ch)
{
	struct kgdb_nmi_tty_priv *priv;
	char c = ch;

	if (!kgdb_nmi_port || ch < 0)
		return;
	/*
	 * Can't use port->tty->driver_data as tty might be not there. Timer
	 * will check for tty and will get the ref, but here we don't have to
	 * do that, and actually, we can't: we're in NMI context, no locks are
	 * possible.
	 */
	priv = container_of(kgdb_nmi_port, struct kgdb_nmi_tty_priv, port);
	kfifo_in(&priv->fifo, &c, 1);
}

static int kgdb_nmi_poll_one_knock(void)
{
	static int n;
	int c;
	const char *magic = kgdb_nmi_magic;
	size_t m = strlen(magic);
	bool printch = false;

	c = dbg_io_ops->read_char();
	if (c == NO_POLL_CHAR)
		return c;

	if (!kgdb_nmi_knock && (c == '\r' || c == '\n')) {
		return 1;
	} else if (c == magic[n]) {
		n = (n + 1) % m;
		if (!n)
			return 1;
		printch = true;
	} else {
		n = 0;
	}

	if (atomic_read(&kgdb_nmi_num_readers)) {
		kgdb_tty_recv(c);
		return 0;
	}

	if (printch) {
		kdb_printf("%c", c);
		return 0;
	}

	kdb_printf("\r%s %s to enter the debugger> %*s",
		   kgdb_nmi_knock ? "Type" : "Hit",
		   kgdb_nmi_knock ? magic  : "<return>", (int)m, "");
	while (m--)
		kdb_printf("\b");
	return 0;
}

/**
 * kgdb_nmi_poll_knock - Check if it is time to enter the debugger
 *
 * "Serial ports are often noisy, especially when muxed over another port (we
 * often use serial over the headset connector). Noise on the async command
 * line just causes characters that are ignored, on a command line that blocked
 * execution noise would be catastrophic." -- Colin Cross
 *
 * So, this function implements KGDB/KDB knocking on the serial line: we won't
 * enter the debugger until we receive a known magic phrase (which is actually
 * "$3#33", known as "escape to KDB" command. There is also a relaxed variant
 * of knocking, i.e. just pressing the return key is enough to enter the
 * debugger. And if knocking is disabled, the function always returns 1.
 */
bool kgdb_nmi_poll_knock(void)
{
	if (kgdb_nmi_knock < 0)
		return true;

	while (1) {
		int ret;

		ret = kgdb_nmi_poll_one_knock();
		if (ret == NO_POLL_CHAR)
			return false;
		else if (ret == 1)
			break;
	}
	return true;
}

/*
 * The tasklet is cheap, it does not cause wakeups when reschedules itself,
 * instead it waits for the next tick.
 */
static void kgdb_nmi_tty_receiver(struct timer_list *t)
{
	struct kgdb_nmi_tty_priv *priv = from_timer(priv, t, timer);
	char ch;

	priv->timer.expires = jiffies + (HZ/100);
	add_timer(&priv->timer);

	if (likely(!atomic_read(&kgdb_nmi_num_readers) ||
		   !kfifo_len(&priv->fifo)))
		return;

	while (kfifo_out(&priv->fifo, &ch, 1))
		tty_insert_flip_char(&priv->port, ch, TTY_NORMAL);
	tty_flip_buffer_push(&priv->port);
}

static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty)
{
	struct kgdb_nmi_tty_priv *priv =
	    container_of(port, struct kgdb_nmi_tty_priv, port);

	kgdb_nmi_port = port;
	priv->timer.expires = jiffies + (HZ/100);
	add_timer(&priv->timer);

	return 0;
}

static void kgdb_nmi_tty_shutdown(struct tty_port *port)
{
	struct kgdb_nmi_tty_priv *priv =
	    container_of(port, struct kgdb_nmi_tty_priv, port);

	del_timer(&priv->timer);
	kgdb_nmi_port = NULL;
}

static const struct tty_port_operations kgdb_nmi_tty_port_ops = {
	.activate	= kgdb_nmi_tty_activate,
	.shutdown	= kgdb_nmi_tty_shutdown,
};

static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty)
{
	struct kgdb_nmi_tty_priv *priv;
	int ret;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	INIT_KFIFO(priv->fifo);
	timer_setup(&priv->timer, kgdb_nmi_tty_receiver, 0);
	tty_port_init(&priv->port);
	priv->port.ops = &kgdb_nmi_tty_port_ops;
	tty->driver_data = priv;

	ret = tty_port_install(&priv->port, drv, tty);
	if (ret) {
		pr_err("%s: can't install tty port: %d\n", __func__, ret);
		goto err;
	}
	return 0;
err:
	tty_port_destroy(&priv->port);
	kfree(priv);
	return ret;
}

static void kgdb_nmi_tty_cleanup(struct tty_struct *tty)
{
	struct kgdb_nmi_tty_priv *priv = tty->driver_data;

	tty->driver_data = NULL;
	tty_port_destroy(&priv->port);
	kfree(priv);
}

static int kgdb_nmi_tty_open(struct tty_struct *tty, struct file *file)
{
	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
	unsigned int mode = file->f_flags & O_ACCMODE;
	int ret;

	ret = tty_port_open(&priv->port, tty, file);
	if (!ret && (mode == O_RDONLY || mode == O_RDWR))
		atomic_inc(&kgdb_nmi_num_readers);

	return ret;
}

static void kgdb_nmi_tty_close(struct tty_struct *tty, struct file *file)
{
	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
	unsigned int mode = file->f_flags & O_ACCMODE;

	if (mode == O_RDONLY || mode == O_RDWR)
		atomic_dec(&kgdb_nmi_num_readers);

	tty_port_close(&priv->port, tty, file);
}

static void kgdb_nmi_tty_hangup(struct tty_struct *tty)
{
	struct kgdb_nmi_tty_priv *priv = tty->driver_data;

	tty_port_hangup(&priv->port);
}

static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty)
{
	/* Actually, we can handle any amount as we use polled writes. */
	return 2048;
}

static int kgdb_nmi_tty_write(struct tty_struct *tty, const unchar *buf, int c)
{
	int i;

	for (i = 0; i < c; i++)
		dbg_io_ops->write_char(buf[i]);
	return c;
}

static const struct tty_operations kgdb_nmi_tty_ops = {
	.open		= kgdb_nmi_tty_open,
	.close		= kgdb_nmi_tty_close,
	.install	= kgdb_nmi_tty_install,
	.cleanup	= kgdb_nmi_tty_cleanup,
	.hangup		= kgdb_nmi_tty_hangup,
	.write_room	= kgdb_nmi_tty_write_room,
	.write		= kgdb_nmi_tty_write,
};

int kgdb_register_nmi_console(void)
{
	int ret;

	if (!arch_kgdb_ops.enable_nmi)
		return 0;

	kgdb_nmi_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
	if (IS_ERR(kgdb_nmi_tty_driver)) {
		pr_err("%s: cannot allocate tty\n", __func__);
		return PTR_ERR(kgdb_nmi_tty_driver);
	}
	kgdb_nmi_tty_driver->driver_name	= "ttyNMI";
	kgdb_nmi_tty_driver->name		= "ttyNMI";
	kgdb_nmi_tty_driver->num		= 1;
	kgdb_nmi_tty_driver->type		= TTY_DRIVER_TYPE_SERIAL;
	kgdb_nmi_tty_driver->subtype		= SERIAL_TYPE_NORMAL;
	kgdb_nmi_tty_driver->init_termios	= tty_std_termios;
	tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios,
				     KGDB_NMI_BAUD, KGDB_NMI_BAUD);
	tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops);

	ret = tty_register_driver(kgdb_nmi_tty_driver);
	if (ret) {
		pr_err("%s: can't register tty driver: %d\n", __func__, ret);
		goto err_drv_reg;
	}

	register_console(&kgdb_nmi_console);

	return 0;
err_drv_reg:
	tty_driver_kref_put(kgdb_nmi_tty_driver);
	return ret;
}
EXPORT_SYMBOL_GPL(kgdb_register_nmi_console);

int kgdb_unregister_nmi_console(void)
{
	int ret;

	if (!arch_kgdb_ops.enable_nmi)
		return 0;
	arch_kgdb_ops.enable_nmi(0);

	ret = unregister_console(&kgdb_nmi_console);
	if (ret)
		return ret;

	tty_unregister_driver(kgdb_nmi_tty_driver);
	tty_driver_kref_put(kgdb_nmi_tty_driver);

	return 0;
}
EXPORT_SYMBOL_GPL(kgdb_unregister_nmi_console);
