// SPDX-License-Identifier: GPL-2.0
/*
 * Based on the same principle as kgdboe using the NETPOLL api, this
 * driver uses a console polling api to implement a gdb serial inteface
 * which is multiplexed on a console port.
 *
 * Maintainer: Jason Wessel <jason.wessel@windriver.com>
 *
 * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/kgdb.h>
#include <linux/kdb.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>

#define MAX_CONFIG_LEN		40

static struct kgdb_io		kgdboc_io_ops;

/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
static int configured		= -1;
static DEFINE_MUTEX(config_mutex);

static char config[MAX_CONFIG_LEN];
static struct kparam_string kps = {
	.string			= config,
	.maxlen			= MAX_CONFIG_LEN,
};

static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
static struct tty_driver	*kgdb_tty_driver;
static int			kgdb_tty_line;

static struct platform_device *kgdboc_pdev;

#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
static struct kgdb_io		kgdboc_earlycon_io_ops;
static int                      (*earlycon_orig_exit)(struct console *con);
#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */

#ifdef CONFIG_KDB_KEYBOARD
static int kgdboc_reset_connect(struct input_handler *handler,
				struct input_dev *dev,
				const struct input_device_id *id)
{
	input_reset_device(dev);

	/* Return an error - we do not want to bind, just to reset */
	return -ENODEV;
}

static void kgdboc_reset_disconnect(struct input_handle *handle)
{
	/* We do not expect anyone to actually bind to us */
	BUG();
}

static const struct input_device_id kgdboc_reset_ids[] = {
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
		.evbit = { BIT_MASK(EV_KEY) },
	},
	{ }
};

static struct input_handler kgdboc_reset_handler = {
	.connect	= kgdboc_reset_connect,
	.disconnect	= kgdboc_reset_disconnect,
	.name		= "kgdboc_reset",
	.id_table	= kgdboc_reset_ids,
};

static DEFINE_MUTEX(kgdboc_reset_mutex);

static void kgdboc_restore_input_helper(struct work_struct *dummy)
{
	/*
	 * We need to take a mutex to prevent several instances of
	 * this work running on different CPUs so they don't try
	 * to register again already registered handler.
	 */
	mutex_lock(&kgdboc_reset_mutex);

	if (input_register_handler(&kgdboc_reset_handler) == 0)
		input_unregister_handler(&kgdboc_reset_handler);

	mutex_unlock(&kgdboc_reset_mutex);
}

static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);

static void kgdboc_restore_input(void)
{
	if (likely(system_state == SYSTEM_RUNNING))
		schedule_work(&kgdboc_restore_input_work);
}

static int kgdboc_register_kbd(char **cptr)
{
	if (strncmp(*cptr, "kbd", 3) == 0 ||
		strncmp(*cptr, "kdb", 3) == 0) {
		if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
			kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
			kdb_poll_idx++;
			if (cptr[0][3] == ',')
				*cptr += 4;
			else
				return 1;
		}
	}
	return 0;
}

static void kgdboc_unregister_kbd(void)
{
	int i;

	for (i = 0; i < kdb_poll_idx; i++) {
		if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
			kdb_poll_idx--;
			kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
			kdb_poll_funcs[kdb_poll_idx] = NULL;
			i--;
		}
	}
	flush_work(&kgdboc_restore_input_work);
}
#else /* ! CONFIG_KDB_KEYBOARD */
#define kgdboc_register_kbd(x) 0
#define kgdboc_unregister_kbd()
#define kgdboc_restore_input()
#endif /* ! CONFIG_KDB_KEYBOARD */

#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
static void cleanup_earlycon(void)
{
	if (kgdboc_earlycon_io_ops.cons)
		kgdb_unregister_io_module(&kgdboc_earlycon_io_ops);
}
#else /* !IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
static inline void cleanup_earlycon(void) { }
#endif /* !IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */

static void cleanup_kgdboc(void)
{
	cleanup_earlycon();

	if (configured != 1)
		return;

	if (kgdb_unregister_nmi_console())
		return;
	kgdboc_unregister_kbd();
	kgdb_unregister_io_module(&kgdboc_io_ops);
}

static int configure_kgdboc(void)
{
	struct tty_driver *p;
	int tty_line = 0;
	int err = -ENODEV;
	char *cptr = config;
	struct console *cons;

	if (!strlen(config) || isspace(config[0])) {
		err = 0;
		goto noconfig;
	}

	kgdboc_io_ops.cons = NULL;
	kgdb_tty_driver = NULL;

	kgdboc_use_kms = 0;
	if (strncmp(cptr, "kms,", 4) == 0) {
		cptr += 4;
		kgdboc_use_kms = 1;
	}

	if (kgdboc_register_kbd(&cptr))
		goto do_register;

	/*
	 * tty_find_polling_driver() can call uart_set_options()
	 * (via poll_init) to configure the uart. Take the console_list_lock
	 * in order to synchronize against register_console(), which can also
	 * configure the uart via uart_set_options(). This also allows safe
	 * traversal of the console list.
	 */
	console_list_lock();

	p = tty_find_polling_driver(cptr, &tty_line);
	if (!p) {
		console_list_unlock();
		goto noconfig;
	}

	/*
	 * Take console_lock to serialize device() callback with
	 * other console operations. For example, fg_console is
	 * modified under console_lock when switching vt.
	 */
	console_lock();

	for_each_console(cons) {
		int idx;
		if (cons->device && cons->device(cons, &idx) == p &&
		    idx == tty_line) {
			kgdboc_io_ops.cons = cons;
			break;
		}
	}

	console_unlock();

	console_list_unlock();

	kgdb_tty_driver = p;
	kgdb_tty_line = tty_line;

do_register:
	err = kgdb_register_io_module(&kgdboc_io_ops);
	if (err)
		goto noconfig;

	err = kgdb_register_nmi_console();
	if (err)
		goto nmi_con_failed;

	configured = 1;

	return 0;

nmi_con_failed:
	kgdb_unregister_io_module(&kgdboc_io_ops);
noconfig:
	kgdboc_unregister_kbd();
	configured = 0;

	return err;
}

static int kgdboc_probe(struct platform_device *pdev)
{
	int ret = 0;

	mutex_lock(&config_mutex);
	if (configured != 1) {
		ret = configure_kgdboc();

		/* Convert "no device" to "defer" so we'll keep trying */
		if (ret == -ENODEV)
			ret = -EPROBE_DEFER;
	}
	mutex_unlock(&config_mutex);

	return ret;
}

static struct platform_driver kgdboc_platform_driver = {
	.probe = kgdboc_probe,
	.driver = {
		.name = "kgdboc",
		.suppress_bind_attrs = true,
	},
};

static int __init init_kgdboc(void)
{
	int ret;

	/*
	 * kgdboc is a little bit of an odd "platform_driver".  It can be
	 * up and running long before the platform_driver object is
	 * created and thus doesn't actually store anything in it.  There's
	 * only one instance of kgdb so anything is stored as global state.
	 * The platform_driver is only created so that we can leverage the
	 * kernel's mechanisms (like -EPROBE_DEFER) to call us when our
	 * underlying tty is ready.  Here we init our platform driver and
	 * then create the single kgdboc instance.
	 */
	ret = platform_driver_register(&kgdboc_platform_driver);
	if (ret)
		return ret;

	kgdboc_pdev = platform_device_alloc("kgdboc", PLATFORM_DEVID_NONE);
	if (!kgdboc_pdev) {
		ret = -ENOMEM;
		goto err_did_register;
	}

	ret = platform_device_add(kgdboc_pdev);
	if (!ret)
		return 0;

	platform_device_put(kgdboc_pdev);

err_did_register:
	platform_driver_unregister(&kgdboc_platform_driver);
	return ret;
}

static void exit_kgdboc(void)
{
	mutex_lock(&config_mutex);
	cleanup_kgdboc();
	mutex_unlock(&config_mutex);

	platform_device_unregister(kgdboc_pdev);
	platform_driver_unregister(&kgdboc_platform_driver);
}

static int kgdboc_get_char(void)
{
	if (!kgdb_tty_driver)
		return -1;
	return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
						kgdb_tty_line);
}

static void kgdboc_put_char(u8 chr)
{
	if (!kgdb_tty_driver)
		return;
	kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
					kgdb_tty_line, chr);
}

static int param_set_kgdboc_var(const char *kmessage,
				const struct kernel_param *kp)
{
	size_t len = strlen(kmessage);
	int ret = 0;

	if (len >= MAX_CONFIG_LEN) {
		pr_err("config string too long\n");
		return -ENOSPC;
	}

	if (kgdb_connected) {
		pr_err("Cannot reconfigure while KGDB is connected.\n");
		return -EBUSY;
	}

	mutex_lock(&config_mutex);

	strcpy(config, kmessage);
	/* Chop out \n char as a result of echo */
	if (len && config[len - 1] == '\n')
		config[len - 1] = '\0';

	if (configured == 1)
		cleanup_kgdboc();

	/*
	 * Configure with the new params as long as init already ran.
	 * Note that we can get called before init if someone loads us
	 * with "modprobe kgdboc kgdboc=..." or if they happen to use
	 * the odd syntax of "kgdboc.kgdboc=..." on the kernel command.
	 */
	if (configured >= 0)
		ret = configure_kgdboc();

	/*
	 * If we couldn't configure then clear out the config.  Note that
	 * specifying an invalid config on the kernel command line vs.
	 * through sysfs have slightly different behaviors.  If we fail
	 * to configure what was specified on the kernel command line
	 * we'll leave it in the 'config' and return -EPROBE_DEFER from
	 * our probe.  When specified through sysfs userspace is
	 * responsible for loading the tty driver before setting up.
	 */
	if (ret)
		config[0] = '\0';

	mutex_unlock(&config_mutex);

	return ret;
}

static int dbg_restore_graphics;

static void kgdboc_pre_exp_handler(void)
{
	if (!dbg_restore_graphics && kgdboc_use_kms) {
		dbg_restore_graphics = 1;
		con_debug_enter(vc_cons[fg_console].d);
	}
	/* Increment the module count when the debugger is active */
	if (!kgdb_connected)
		try_module_get(THIS_MODULE);
}

static void kgdboc_post_exp_handler(void)
{
	/* decrement the module count when the debugger detaches */
	if (!kgdb_connected)
		module_put(THIS_MODULE);
	if (kgdboc_use_kms && dbg_restore_graphics) {
		dbg_restore_graphics = 0;
		con_debug_leave();
	}
	kgdboc_restore_input();
}

static struct kgdb_io kgdboc_io_ops = {
	.name			= "kgdboc",
	.read_char		= kgdboc_get_char,
	.write_char		= kgdboc_put_char,
	.pre_exception		= kgdboc_pre_exp_handler,
	.post_exception		= kgdboc_post_exp_handler,
};

#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
static int kgdboc_option_setup(char *opt)
{
	if (!opt) {
		pr_err("config string not provided\n");
		return 1;
	}

	if (strlen(opt) >= MAX_CONFIG_LEN) {
		pr_err("config string too long\n");
		return 1;
	}
	strcpy(config, opt);

	return 1;
}

__setup("kgdboc=", kgdboc_option_setup);


/* This is only available if kgdboc is a built in for early debugging */
static int __init kgdboc_early_init(char *opt)
{
	kgdboc_option_setup(opt);
	configure_kgdboc();
	return 0;
}

early_param("ekgdboc", kgdboc_early_init);

static int kgdboc_earlycon_get_char(void)
{
	char c;

	if (!kgdboc_earlycon_io_ops.cons->read(kgdboc_earlycon_io_ops.cons,
					       &c, 1))
		return NO_POLL_CHAR;

	return c;
}

static void kgdboc_earlycon_put_char(u8 chr)
{
	kgdboc_earlycon_io_ops.cons->write(kgdboc_earlycon_io_ops.cons, &chr,
					   1);
}

static void kgdboc_earlycon_pre_exp_handler(void)
{
	struct console *con;
	static bool already_warned;
	int cookie;

	if (already_warned)
		return;

	/*
	 * When the first normal console comes up the kernel will take all
	 * the boot consoles out of the list.  Really, we should stop using
	 * the boot console when it does that but until a TTY is registered
	 * we have no other choice so we keep using it.  Since not all
	 * serial drivers might be OK with this, print a warning once per
	 * boot if we detect this case.
	 */
	cookie = console_srcu_read_lock();
	for_each_console_srcu(con) {
		if (con == kgdboc_earlycon_io_ops.cons)
			break;
	}
	console_srcu_read_unlock(cookie);
	if (con)
		return;

	already_warned = true;
	pr_warn("kgdboc_earlycon is still using bootconsole\n");
}

static int kgdboc_earlycon_deferred_exit(struct console *con)
{
	/*
	 * If we get here it means the boot console is going away but we
	 * don't yet have a suitable replacement.  Don't pass through to
	 * the original exit routine.  We'll call it later in our deinit()
	 * function.  For now, restore the original exit() function pointer
	 * as a sentinal that we've hit this point.
	 */
	con->exit = earlycon_orig_exit;

	return 0;
}

static void kgdboc_earlycon_deinit(void)
{
	if (!kgdboc_earlycon_io_ops.cons)
		return;

	if (kgdboc_earlycon_io_ops.cons->exit == kgdboc_earlycon_deferred_exit)
		/*
		 * kgdboc_earlycon is exiting but original boot console exit
		 * was never called (AKA kgdboc_earlycon_deferred_exit()
		 * didn't ever run).  Undo our trap.
		 */
		kgdboc_earlycon_io_ops.cons->exit = earlycon_orig_exit;
	else if (kgdboc_earlycon_io_ops.cons->exit)
		/*
		 * We skipped calling the exit() routine so we could try to
		 * keep using the boot console even after it went away.  We're
		 * finally done so call the function now.
		 */
		kgdboc_earlycon_io_ops.cons->exit(kgdboc_earlycon_io_ops.cons);

	kgdboc_earlycon_io_ops.cons = NULL;
}

static struct kgdb_io kgdboc_earlycon_io_ops = {
	.name			= "kgdboc_earlycon",
	.read_char		= kgdboc_earlycon_get_char,
	.write_char		= kgdboc_earlycon_put_char,
	.pre_exception		= kgdboc_earlycon_pre_exp_handler,
	.deinit			= kgdboc_earlycon_deinit,
};

#define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name)
static char kgdboc_earlycon_param[MAX_CONSOLE_NAME_LEN] __initdata;
static bool kgdboc_earlycon_late_enable __initdata;

static int __init kgdboc_earlycon_init(char *opt)
{
	struct console *con;

	kdb_init(KDB_INIT_EARLY);

	/*
	 * Look for a matching console, or if the name was left blank just
	 * pick the first one we find.
	 */

	/*
	 * Hold the console_list_lock to guarantee that no consoles are
	 * unregistered until the kgdboc_earlycon setup is complete.
	 * Trapping the exit() callback relies on exit() not being
	 * called until the trap is setup. This also allows safe
	 * traversal of the console list and race-free reading of @flags.
	 */
	console_list_lock();
	for_each_console(con) {
		if (con->write && con->read &&
		    (con->flags & (CON_BOOT | CON_ENABLED)) &&
		    (!opt || !opt[0] || strcmp(con->name, opt) == 0))
			break;
	}

	if (!con) {
		/*
		 * Both earlycon and kgdboc_earlycon are initialized during
		 * early parameter parsing. We cannot guarantee earlycon gets
		 * in first and, in any case, on ACPI systems earlycon may
		 * defer its own initialization (usually to somewhere within
		 * setup_arch() ). To cope with either of these situations
		 * we can defer our own initialization to a little later in
		 * the boot.
		 */
		if (!kgdboc_earlycon_late_enable) {
			pr_info("No suitable earlycon yet, will try later\n");
			if (opt)
				strscpy(kgdboc_earlycon_param, opt,
					sizeof(kgdboc_earlycon_param));
			kgdboc_earlycon_late_enable = true;
		} else {
			pr_info("Couldn't find kgdb earlycon\n");
		}
		goto unlock;
	}

	kgdboc_earlycon_io_ops.cons = con;
	pr_info("Going to register kgdb with earlycon '%s'\n", con->name);
	if (kgdb_register_io_module(&kgdboc_earlycon_io_ops) != 0) {
		kgdboc_earlycon_io_ops.cons = NULL;
		pr_info("Failed to register kgdb with earlycon\n");
	} else {
		/* Trap exit so we can keep earlycon longer if needed. */
		earlycon_orig_exit = con->exit;
		con->exit = kgdboc_earlycon_deferred_exit;
	}

unlock:
	console_list_unlock();

	/* Non-zero means malformed option so we always return zero */
	return 0;
}

early_param("kgdboc_earlycon", kgdboc_earlycon_init);

/*
 * This is only intended for the late adoption of an early console.
 *
 * It is not a reliable way to adopt regular consoles because we can not
 * control what order console initcalls are made and, in any case, many
 * regular consoles are registered much later in the boot process than
 * the console initcalls!
 */
static int __init kgdboc_earlycon_late_init(void)
{
	if (kgdboc_earlycon_late_enable)
		kgdboc_earlycon_init(kgdboc_earlycon_param);
	return 0;
}
console_initcall(kgdboc_earlycon_late_init);

#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */

module_init(init_kgdboc);
module_exit(exit_kgdboc);
module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
MODULE_DESCRIPTION("KGDB Console TTY Driver");
MODULE_LICENSE("GPL");
