在2023年10月27日十月 下午7:26,Jiaxun Yang写道: > UHI is MIPS's implementation of semihosting. > Add an earlycon driver to help with debugging on boot. > > This driver is capable for print log using UHI's "Plog" or interact > with KGDB using UHI's stdio function. > > Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> > --- > drivers/tty/serial/Kconfig | 13 ++++ > drivers/tty/serial/Makefile | 1 + > drivers/tty/serial/earlycon-mips-uhi.c | 85 ++++++++++++++++++++++++++ > 3 files changed, 99 insertions(+) > create mode 100644 drivers/tty/serial/earlycon-mips-uhi.c > > diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig > index bdc568a4ab66..04c62c6b45cd 100644 > --- a/drivers/tty/serial/Kconfig > +++ b/drivers/tty/serial/Kconfig > @@ -85,6 +85,19 @@ config SERIAL_EARLYCON_SEMIHOST > This is enabled with "earlycon=smh" on the kernel command line. > The console is enabled when early_param is processed. > > +config SERIAL_EARLYCON_UHI ^ Oops there is a symbol name mismatch, will fix in v2. Sorry for the noise. Thanks - Jiaxun > + bool "Early console using MIPS UHI semihosting" > + depends on MIPS > + select SERIAL_CORE > + select SERIAL_CORE_CONSOLE > + select SERIAL_EARLYCON > + help > + Support for early debug console using UHI semihosting. > + This enables the console before standard serial driver is probed. > + This is enabled with "earlycon=uhi" or "earlycon=uhi_stdio" on the > + kernel command line. > + The console is enabled when early_param is processed. > + > config SERIAL_EARLYCON_RISCV_SBI > bool "Early console using RISC-V SBI" > depends on RISCV_SBI_V01 > diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile > index f6b8c220dcfb..ef5e9c87aea1 100644 > --- a/drivers/tty/serial/Makefile > +++ b/drivers/tty/serial/Makefile > @@ -9,6 +9,7 @@ serial_base-y := serial_core.o serial_base_bus.o > serial_ctrl.o serial_port.o > obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o > obj-$(CONFIG_SERIAL_EARLYCON_SEMIHOST) += earlycon-semihost.o > obj-$(CONFIG_SERIAL_EARLYCON_RISCV_SBI) += earlycon-riscv-sbi.o > +obj-$(CONFIG_SERIAL_EARLYCON_MIPS_UHI) += earlycon-mips-uhi.o > > # These Sparc drivers have to appear before others such as 8250 > # which share ttySx minor node space. Otherwise console device > diff --git a/drivers/tty/serial/earlycon-mips-uhi.c > b/drivers/tty/serial/earlycon-mips-uhi.c > new file mode 100644 > index 000000000000..002bb2c37064 > --- /dev/null > +++ b/drivers/tty/serial/earlycon-mips-uhi.c > @@ -0,0 +1,85 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * MIPS UHI semihosting based earlycon > + * > + * Copyright (C) 2023 Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> > + */ > + > +#include <linux/kernel.h> > +#include <linux/console.h> > +#include <linux/init.h> > +#include <linux/serial_core.h> > +#include <asm/uhi.h> > + > +static int stdin_fd = -1; > +static int stdout_fd = -1; > + > +static void uhi_plog_write(struct console *con, const char *s, > unsigned int n) > +{ > + uhi_plog(s, 0); > +} > + > +static void uhi_stdout_write(struct console *con, const char *s, > unsigned int n) > +{ > + if (stdout_fd < 0) > + return; > + > + uhi_write(stdout_fd, s, n); > +} > + > +#ifdef CONFIG_CONSOLE_POLL > +static int uhi_stdin_read(struct console *con, char *s, unsigned int n) > +{ > + if (stdin_fd < 0) > + return 0; > + > + return uhi_read(stdin_fd, s, n); > +} > +#endif > + > +static int uhi_stdio_fd_open(struct console *co, char *options) > +{ > + /* > + * You have to open both stdin and stdout to get console work > + * properly on some old CodeScape debugger. > + */ > + stdin_fd = uhi_open("/dev/stdin", UHI_O_RDONLY, 0); > + stdout_fd = uhi_open("/dev/stdout", UHI_O_WRONLY, 0); > + > + return (stdin_fd < 0 || stdout_fd < 0) ? -ENODEV : 0; > +} > + > +static int uhi_stdio_fd_close(struct console *co) > +{ > + int ret1 = 0, ret2 = 0; > + > + if (stdin_fd >= 0) > + ret1 = uhi_close(stdin_fd); > + if (stdout_fd >= 0) > + ret2 = uhi_close(stdout_fd); > + > + return (ret1 < 0 || ret2 < 0) ? -ENODEV : 0; > +} > + > +static int > +__init early_uhi_setup(struct earlycon_device *device, const char *opt) > +{ > + device->con->write = uhi_plog_write; > + return 0; > +} > + > +static int > +__init early_uhi_stdio_setup(struct earlycon_device *device, const > char *opt) > +{ > + > + device->con->setup = uhi_stdio_fd_open; > + device->con->exit = uhi_stdio_fd_close; > + device->con->write = uhi_stdout_write; > +#ifdef CONFIG_CONSOLE_POLL > + device->con->read = uhi_stdin_read; > +#endif > + return 0; > +} > + > +EARLYCON_DECLARE(uhi, early_uhi_setup); > +EARLYCON_DECLARE(uhi_stdio, early_uhi_stdio_setup); > -- > 2.34.1 -- - Jiaxun