Skip to contentSkip to conversation

Generic serial earlycon

PATCH In review Rob Herring 5 participants 30 messages Apr 18, 2014 – Jun 11, 2014

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

v2 cover Generic serial earlycon

From: Rob Herring <[email protected]>

This started out as an attempt to add arm64's earlyprintk support to ARM in order to get an earlier, runtime setup console on multi-platform kernels. The first issue was needing the fixmap support which conveniently Mark Salter was working on and is mostly in place now. Like many things on ARM and arm64 now, it then became where do I put the now common, shared code. After digging more into various early console/printk support, it turns out the 8250_early.c setup code was the best starting point.

This is tested on arm64 and ARM with pl011 and 8250. The ARM support also requires fixmap and fixed mapping support which are not yet in place. I have some patches in my tree to support fixmap, but they need some more work. Fortunately, once fixmap is in place, it is just a Kconfig option to enable earlycon support on ARM. A git tree is available here[1].

I'm also working on a follow on series which adds DT based earlycon setup, but that is dependent on some FDT improvements to support FDT based address translation.

Rob

[1] git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git earlycon

Rob Herring (7):
x86: move FIX_EARLYCON_MEM kconfig into x86
tty/serial: add generic serial earlycon
tty/serial: convert 8250 to generic earlycon
tty/serial: pl011: add generic earlycon support
tty/serial: add arm/arm64 semihosting earlycon
arm64: enable FIX_EARLYCON_MEM kconfig
arm64: remove arch specific earlyprintk

 Documentation/kernel-parameters.txt        |   9 ++
 arch/arm64/Kconfig                         |   3 +
 arch/arm64/Kconfig.debug                   |   9 --
 arch/arm64/kernel/Makefile                 |   1 -
 arch/arm64/kernel/early_printk.c           | 158 -----------------------------
 arch/x86/Kconfig                           |   3 +
 drivers/tty/serial/8250/8250_early.c       | 138 +++----------------------
 drivers/tty/serial/8250/Kconfig            |   6 +-
 drivers/tty/serial/Kconfig                 |  18 ++++
 drivers/tty/serial/Makefile                |   3 +
 drivers/tty/serial/amba-pl011.c            |  30 +++++-
 drivers/tty/serial/earlycon-arm-semihost.c |  61 +++++++++++
 drivers/tty/serial/earlycon.c              | 152 +++++++++++++++++++++++++++
 include/linux/serial_core.h                |  16 +++
 14 files changed, 310 insertions(+), 297 deletions(-)
 delete mode 100644 arch/arm64/kernel/early_printk.c
 create mode 100644 drivers/tty/serial/earlycon-arm-semihost.c
 create mode 100644 drivers/tty/serial/earlycon.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/7 x86: move FIX_EARLYCON_MEM kconfig into x86

From: Rob Herring <[email protected]>

In preparation to support FIX_EARLYCON_MEM on other arches, make the option per arch.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc x86 at kernel.org
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 arch/x86/Kconfig                | 3 +++
 drivers/tty/serial/8250/Kconfig | 5 -----
 2 files changed, 3 insertions(+), 5 deletions(-)
arch/x86/Kconfig +3 -0
index 25d2c6f..0fb6cfd 100644
@@ -261,6 +261,9 @@ config ARCH_HWEIGHT_CFLAGS
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
 
+config FIX_EARLYCON_MEM
+	def_bool y
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
drivers/tty/serial/8250/Kconfig +0 -5
index 2332991..91f1d83 100644
@@ -90,11 +90,6 @@ config SERIAL_8250_CONSOLE
 
 	  If unsure, say N.
 
-config FIX_EARLYCON_MEM
-	bool
-	depends on X86
-	default y
-
 config SERIAL_8250_GSC
 	tristate
 	depends on SERIAL_8250 && GSC
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/7 tty/serial: add generic serial earlycon

In reply to Rob Herring

From: Rob Herring <[email protected]>

This introduces generic earlycon infrastructure for serial devices based on the 8250 earlycon. This allows for supporting earlycon option with other serial devices. The earlycon output is enabled at the time early_params are processed.

Only architectures that have fixmap support or have functional ioremap when early_params are processed are supported. This is the same restriction that the 8250 driver had.

Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>

---
v2:
- Use set_fixmap_io/ioremap instead of set_fixmap_nocache/ioremap_nocache.
- Do the mapping outside of option parsing function.

 drivers/tty/serial/Kconfig    |   7 ++
 drivers/tty/serial/Makefile   |   2 +
 drivers/tty/serial/earlycon.c | 152 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/serial_core.h   |  16 +++++
 4 files changed, 177 insertions(+)
 create mode 100644 drivers/tty/serial/earlycon.c
drivers/tty/serial/Kconfig +7 -0
index 2e6d8dd..3b7c19b 100644
@@ -7,6 +7,13 @@ if TTY
 menu "Serial drivers"
 	depends on HAS_IOMEM
 
+config SERIAL_EARLYCON
+	bool
+	help
+	  Support for early consoles with the earlycon parameter. This enables
+	  the console before standard serial driver is probed. The console is
+	  enabled when early_param is processed.
+
 source "drivers/tty/serial/8250/Kconfig"
 
 comment "Non-8250 serial port support"
drivers/tty/serial/Makefile +2 -0
index 3680854..8af1415 100644
@@ -5,6 +5,8 @@
 obj-$(CONFIG_SERIAL_CORE) += serial_core.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
+obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
+
 # These Sparc drivers have to appear before others such as 8250
 # which share ttySx minor node space.  Otherwise console device
 # names change and other unplesantries.
drivers/tty/serial/earlycon.c new file +152 -0

152 lines not on this page · raw message

include/linux/serial_core.h +16 -0
index f729be9..7a15b5b 100644
@@ -285,6 +285,22 @@ static inline int uart_poll_timeout(struct uart_port *port)
 /*
  * Console helpers.
  */
+struct earlycon_device {
+	struct console *con;
+	struct uart_port port;
+	char options[16];		/* e.g., 115200n8 */
+	unsigned int baud;
+};
+int setup_earlycon(char *buf, const char *match,
+		   int (*setup)(struct earlycon_device *, const char *));
+
+#define EARLYCON_DECLARE(name, func) \
+static int __init name ## _setup_earlycon(char *buf) \
+{ \
+	return setup_earlycon(buf, __stringify(name), func); \
+} \
+early_param("earlycon", name ## _setup_earlycon);
+
 struct uart_port *uart_get_console(struct uart_port *ports, int nr,
 				   struct console *c);
 void uart_parse_options(char *options, int *baud, int *parity, int *bits,
Signature · 1 line
1.9.1
#3 lore raw

PATCH v2 3/7 tty/serial: convert 8250 to generic earlycon

In reply to Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)
drivers/tty/serial/8250/8250_early.c +15 -123
index c100d63..e83c9db 100644
@@ -35,18 +35,8 @@
 #include <linux/serial_8250.h>
 #include <asm/io.h>
 #include <asm/serial.h>
-#ifdef CONFIG_FIX_EARLYCON_MEM
-#include <asm/pgtable.h>
-#include <asm/fixmap.h>
-#endif
 
-struct early_serial8250_device {
-	struct uart_port port;
-	char options[16];		/* e.g., 115200n8 */
-	unsigned int baud;
-};
-
-static struct early_serial8250_device early_device;
+static struct earlycon_device *early_device;
 
 unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
 {
@@ -100,7 +90,7 @@ static void __init serial_putc(struct uart_port *port, int c)
 static void __init early_serial8250_write(struct console *console,
 					const char *s, unsigned int count)
 {
-	struct uart_port *port = &early_device.port;
+	struct uart_port *port = &early_device->port;
 	unsigned int ier;
 
 	/* Save the IER and disable interrupts */
@@ -129,7 +119,7 @@ static unsigned int __init probe_baud(struct uart_port *port)
 	return (port->uartclk / 16) / quot;
 }
 
-static void __init init_port(struct early_serial8250_device *device)
+static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
 	unsigned int divisor;
@@ -148,128 +138,32 @@ static void __init init_port(struct early_serial8250_device *device)
 	serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB);
 }
 
-static int __init parse_options(struct early_serial8250_device *device,
-								char *options)
-{
-	struct uart_port *port = &device->port;
-	int mmio, mmio32, length;
-
-	if (!options)
-		return -ENODEV;
-
-	port->uartclk = BASE_BAUD * 16;
-
-	mmio = !strncmp(options, "mmio,", 5);
-	mmio32 = !strncmp(options, "mmio32,", 7);
-	if (mmio || mmio32) {
-		port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
-		port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
-					       &options, 0);
-		if (mmio32)
-			port->regshift = 2;
-#ifdef CONFIG_FIX_EARLYCON_MEM
-		set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
-					port->mapbase & PAGE_MASK);
-		port->membase =
-			(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
-		port->membase += port->mapbase & ~PAGE_MASK;
-#else
-		port->membase = ioremap_nocache(port->mapbase, 64);
-		if (!port->membase) {
-			printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
-				__func__,
-			       (unsigned long long) port->mapbase);
-			return -ENOMEM;
-		}
-#endif
-	} else if (!strncmp(options, "io,", 3)) {
-		port->iotype = UPIO_PORT;
-		port->iobase = simple_strtoul(options + 3, &options, 0);
-		mmio = 0;
-	} else
-		return -EINVAL;
-
-	options = strchr(options, ',');
-	if (options) {
-		options++;
-		device->baud = simple_strtoul(options, NULL, 0);
-		length = min(strcspn(options, " ") + 1,
-			     (size_t)(sizeof(device->options)));
-		strlcpy(device->options, options, length);
-	} else {
-		device->baud = probe_baud(port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			device->baud);
-	}
-
-	if (mmio || mmio32)
-		printk(KERN_INFO
-		       "Early serial console at MMIO%s 0x%llx (options '%s')\n",
-			mmio32 ? "32" : "",
-			(unsigned long long)port->mapbase,
-			device->options);
-	else
-		printk(KERN_INFO
-		      "Early serial console at I/O port 0x%lx (options '%s')\n",
-			port->iobase,
-			device->options);
-
-	return 0;
-}
-
-static struct console early_serial8250_console __initdata = {
-	.name	= "uart",
-	.write	= early_serial8250_write,
-	.flags	= CON_PRINTBUFFER | CON_BOOT,
-	.index	= -1,
-};
-
-static int __init early_serial8250_setup(char *options)
+static int __init early_serial8250_setup(struct earlycon_device *device,
+					 const char *options)
 {
-	struct early_serial8250_device *device = &early_device;
-	int err;
-
-	if (device->port.membase || device->port.iobase)
+	if (!(device->port.membase || device->port.iobase))
 		return 0;
 
-	err = parse_options(device, options);
-	if (err < 0)
-		return err;
+	if (!device->baud)
+		device->baud = probe_baud(&device->port);
 
 	init_port(device);
-	return 0;
-}
-
-int __init setup_early_serial8250_console(char *cmdline)
-{
-	char *options;
-	int err;
-
-	options = strstr(cmdline, "uart8250,");
-	if (!options) {
-		options = strstr(cmdline, "uart,");
-		if (!options)
-			return 0;
-	}
-
-	options = strchr(cmdline, ',') + 1;
-	err = early_serial8250_setup(options);
-	if (err < 0)
-		return err;
-
-	register_console(&early_serial8250_console);
 
+	early_device = device;
+	device->con->write = early_serial8250_write;
 	return 0;
 }
+EARLYCON_DECLARE(uart8250, early_serial8250_setup);
+EARLYCON_DECLARE(uart, early_serial8250_setup);
 
 int serial8250_find_port_for_earlycon(void)
 {
-	struct early_serial8250_device *device = &early_device;
-	struct uart_port *port = &device->port;
+	struct earlycon_device *device = early_device;
+	struct uart_port *port = device ? &device->port : NULL;
 	int line;
 	int ret;
 
-	if (!device->port.membase && !device->port.iobase)
+	if (!port || (!port->membase && !port->iobase))
 		return -ENODEV;
 
 	line = serial8250_find_port(port);
@@ -284,5 +178,3 @@ int serial8250_find_port_for_earlycon(void)
 
 	return ret;
 }
-
-early_param("earlycon", setup_early_serial8250_console);
drivers/tty/serial/8250/Kconfig +1 -0
index 91f1d83..349ee59 100644
@@ -61,6 +61,7 @@ config SERIAL_8250_CONSOLE
 	bool "Console on 8250/16550 and compatible serial port"
 	depends on SERIAL_8250=y
 	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
 	---help---
 	  If you say Y here, it will be possible to use a serial port as the
 	  system console (the system console is the device which receives all
Signature · 1 line
1.9.1
#4 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 5 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Quoted 7 lines
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

It should produce "early con and regular con".

Thanks

Yinghai

#5 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 14 lines · Yinghai Lu
Quoted 5 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Quoted 7 lines
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)
Quoted 6 lines

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

It should produce "early con and regular con".

This is what I get for running checkpatch and converting simple_strtoul to kstrto* which are not so equivalent. kstrto* will not convert things such as 115200n8 to a number.

Greg, Do you want a fix or for me to respin the series? The fix looks like this:

drivers/tty/serial/earlycon.c +0 -0
index 73bf1e2..c92e830 100644
@@ -53,7 +53,7 @@ static int __init parse_options(struct

earlycon_device *device,
char *options)

 {
        struct uart_port *port = &device->port;
-       int mmio, mmio32, length, ret;
+       int mmio, mmio32, length;
        unsigned long addr;

        if (!options)
@@ -64,25 +64,19 @@ static int __init parse_options(struct
earlycon_device *device,
        if (mmio || mmio32) {
                port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
                options += mmio ? 5 : 7;
-               ret = kstrtoul(options, 0, &addr);
-               if (ret)
-                       return ret;
+               addr = simple_strtoul(options, NULL, 0);
                port->mapbase = addr;
                if (mmio32)
                        port->regshift = 2;
        } else if (!strncmp(options, "io,", 3)) {
                port->iotype = UPIO_PORT;
                options += 3;
-               ret = kstrtoul(options, 0, &addr);
-               if (ret)
-                       return ret;
+               addr = simple_strtoul(options, NULL, 0);
                port->iobase = addr;
                mmio = 0;
        } else if (!strncmp(options, "0x", 2)) {
                port->iotype = UPIO_MEM;
-               ret = kstrtoul(options, 0, &addr);
-               if (ret)
-                       return ret;
+               addr = simple_strtoul(options, NULL, 0);
                port->mapbase = addr;
        } else {
                return -EINVAL;
@@ -93,9 +87,7 @@ static int __init parse_options(struct
earlycon_device *device,
        options = strchr(options, ',');
        if (options) {
                options++;
-               ret = kstrtouint(options, 0, &device->baud);
-               if (ret)
-                       return ret;
+               device->baud = simple_strtoul(options, NULL, 0);
                length = min(strcspn(options, " ") + 1,
                             (size_t)(sizeof(device->options)));
                strlcpy(device->options, options, length);
#6 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 20 lines · Rob Herring
Quoted 19 lines · Yinghai Lu
Quoted 5 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Quoted 7 lines
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

Quoted 7 lines
Quoted 1 line

It should produce "early con and regular con".

This is what I get for running checkpatch and converting simple_strtoul to kstrto* which are not so equivalent. kstrto* will not convert things such as 115200n8 to a number.

Greg, Do you want a fix or for me to respin the series? The fix looks like this:

As this is in my tree now (right?), I need a fix to apply to it.

thanks,

greg k-h

#7 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 23 lines · Greg Kroah-Hartman
Quoted 22 lines · Rob Herring
Quoted 20 lines · Yinghai Lu
Quoted 5 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Quoted 7 lines
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

It should produce "early con and regular con".

Quoted 7 lines
Quoted 5 lines

This is what I get for running checkpatch and converting simple_strtoul to kstrto* which are not so equivalent. kstrto* will not convert things such as 115200n8 to a number.

Greg, Do you want a fix or for me to respin the series? The fix looks like this:

As this is in my tree now (right?), I need a fix to apply to it.

Nevermind, you already sent it...

#8 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 15 lines · Greg Kroah-Hartman
Quoted 15 lines
Quoted 15 lines
Quoted 10 lines
Quoted 3 lines
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

It should produce "early con and regular con".

This is what I get for running checkpatch and converting simple_strtoul to kstrto* which are not so equivalent. kstrto* will not convert things such as 115200n8 to a number.

Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Greg, Do you want a fix or for me to respin the series? The fix looks like this:

As this is in my tree now (right?), I need a fix to apply to it.

Nevermind, you already sent it...

Linus' tree (HEAD=963649d735c8) is spitting out all sorts of garbage on the serial console - as if the baud rate is being periodically set to something weird, and then back to 112500. I see over a dozen blocks of junk interspersed with good output.

This in on ia64 with "console=uart,io,0x3f8" on the command line.

git bisect pointed me here:

d2fd6810a823bcde1ee232668f5689837aafa772 is first bad commit commit d2fd6810a823bcde1ee232668f5689837aafa772

Author: Rob Herring <[email protected]>
Date:   Fri Apr 18 17:19:56 2014 -0500

tty/serial: convert 8250 to generic earlycon

-Tony

#9 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 4 lines · Tony Luck

Linus' tree (HEAD=963649d735c8) is spitting out all sorts of garbage on the serial console - as if the baud rate is being periodically set to something weird, and then back to 112500. I see over a dozen blocks of junk interspersed with good output.

Ah - it seems that I need to be more specific on the cmdline

     console=uart8250,io,0x3f8,115200

makes all the garbage disappear.

Do I need to update: Documentation/ia64/serial.txt which has the example of "console=uart,io,0x3f8"?

-Tony

#10 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 6 lines · Tony Luck
Quoted 4 lines · Tony Luck

Linus' tree (HEAD=963649d735c8) is spitting out all sorts of garbage on the serial console - as if the baud rate is being periodically set to something weird, and then back to 112500. I see over a dozen blocks of junk interspersed with good output.

Quoted 8 lines

Ah - it seems that I need to be more specific on the cmdline

     console=uart8250,io,0x3f8,115200

makes all the garbage disappear.

Do I need to update: Documentation/ia64/serial.txt which has the example of "console=uart,io,0x3f8"?

It should do auto detect of the baud-rate if it is not specified which for 8250 is just reading the baud-rate divider and calculating the baud-rate using the uart clock. It should just reprogram the divider with the same divider value. I don't see anything obvious why this would have broken.

Rob

#11 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 5 lines · Rob Herring

It should do auto detect of the baud-rate if it is not specified which for 8250 is just reading the baud-rate divider and calculating the baud-rate using the uart clock. It should just reprogram the divider with the same divider value. I don't see anything obvious why this would have broken.

Something very weird is happening. Output is good so long as I put the trailing ",115200" on the command line.

But I made early_serial8250_setup() printk() the return value it got from probe_baud() - in case is was somehow getting 115201 or some other silly value ... nope. Exactly 115200.

I also can't explain why the "noise" comes and goes a dozen times during boot,

Does some other place in the kernel look at the "uart..." command line argument?

-Tony

#12 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 14 lines · Tony Luck
Quoted 5 lines · Rob Herring

It should do auto detect of the baud-rate if it is not specified which for 8250 is just reading the baud-rate divider and calculating the baud-rate using the uart clock. It should just reprogram the divider with the same divider value. I don't see anything obvious why this would have broken.

Something very weird is happening. Output is good so long as I put the trailing ",115200" on the command line.

But I made early_serial8250_setup() printk() the return value it got from probe_baud() - in case is was somehow getting 115201 or some other silly value ... nope. Exactly 115200.

Quoted 5 lines

I also can't explain why the "noise" comes and goes a dozen times during boot,

Does some other place in the kernel look at the "uart..." command line argument?

Would you be using drivers/firmware/pcdp.c as that is ia64 only? That shouldn't have an impact that I can see.

Can you print the options string in serial8250_console_setup? Maybe it is getting lost when the real console is setup.

Rob

#13 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

In reply to Tony Luck
Quoted 14 lines · Tony Luck
Quoted 5 lines · Rob Herring

It should do auto detect of the baud-rate if it is not specified which for 8250 is just reading the baud-rate divider and calculating the baud-rate using the uart clock. It should just reprogram the divider with the same divider value. I don't see anything obvious why this would have broken.

Something very weird is happening. Output is good so long as I put the trailing ",115200" on the command line.

But I made early_serial8250_setup() printk() the return value it got from probe_baud() - in case is was somehow getting 115201 or some other silly value ... nope. Exactly 115200.

Quoted 5 lines

I also can't explain why the "noise" comes and goes a dozen times during boot,

Does some other place in the kernel look at the "uart..." command line argument?

I think I figured it out. The function serial8250_find_port_for_earlycon is failing to match 'uart' console to 'ttyS' console and transfer the options. It was also failing to create an option string when the baud rate is probed. Can you try out the below patch?

Rob

8<-------------------------------------------------------------------

drivers/tty/serial/8250/8250_early.c +4 -1
index cfef801..4858b8a 100644
@@ -144,8 +144,11 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 	if (!(device->port.membase || device->port.iobase))
 		return 0;
 
-	if (!device->baud)
+	if (!device->baud) {
 		device->baud = probe_baud(&device->port);
+		snprintf(device->options, sizeof(device->options), "%u",
+			 device->baud);
+	}
 
 	init_port(device);
 
drivers/tty/serial/earlycon.c +1 -1
index 5131b5e..d20e6d8 100644
@@ -25,7 +25,7 @@
 #include <asm/serial.h>
 
 static struct console early_con = {
-	.name =		"earlycon",
+	.name =		"uart",
 	.flags =	CON_PRINTBUFFER | CON_BOOT,
 	.index =	-1,
 };
#14 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 5 lines · Rob Herring

I think I figured it out. The function serial8250_find_port_for_earlycon is failing to match 'uart' console to 'ttyS' console and transfer the options. It was also failing to create an option string when the baud rate is probed. Can you try out the below patch?

Rob,

That works. Thanks for digging deeper into this.

Here's a tag for when you push that patch:

Reported-and-tested-by Tony Luck <[email protected]>

-Tony

#15 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

In reply to Rob Herring
Quoted 33 lines · Rob Herring

On 06/10/2014 03:52 PM, Tony Luck wrote:
I think I figured it out. The function serial8250_find_port_for_earlycon is failing to match 'uart' console to 'ttyS' console and transfer the options. It was also failing to create an option string when the baud rate is probed. Can you try out the below patch?

Rob

8<-------------------------------------------------------------------

drivers/tty/serial/8250/8250_early.c +4 -1
index cfef801..4858b8a 100644
@@ -144,8 +144,11 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
        if (!(device->port.membase || device->port.iobase))
                return 0;
 
-       if (!device->baud)
+       if (!device->baud) {
                device->baud = probe_baud(&device->port);
+               snprintf(device->options, sizeof(device->options), "%u",
+                        device->baud);
+       }
 
        init_port(device);
 
drivers/tty/serial/earlycon.c +0 -0
index 5131b5e..d20e6d8 100644

drivers/tty/serial/earlycon.c line 31

Quoted 8 lines
drivers/tty/serial/earlycon.c +1 -1
@@ -25,7 +25,7 @@
 #include <asm/serial.h>
 
 static struct console early_con = {
-       .name =         "earlycon",
+       .name =         "uart",
        .flags =        CON_PRINTBUFFER | CON_BOOT,
        .index =        -1,
 };

Yes, that is right fix.

For the name in early_con with "uart", please add some comments that serial8250_find_port_for_earlycon() will look for "uart"...

Thanks

Yinghai

#16 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

In reply to Tony Luck
Quoted 19 lines · Tony Luck
Quoted 17 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 16 lines
Quoted 10 lines
Quoted 3 lines
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)

Hi Greg, Rob

This one in tty-next breaks booting: "console=uart8250,io,0x3f8,115200". No early console and regular console anymore.

It should produce "early con and regular con".

This is what I get for running checkpatch and converting simple_strtoul to kstrto* which are not so equivalent. kstrto* will not convert things such as 115200n8 to a number.

Greg, Do you want a fix or for me to respin the series? The fix looks like this:

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

As this is in my tree now (right?), I need a fix to apply to it.

Nevermind, you already sent it...

Linus' tree (HEAD=963649d735c8) is spitting out all sorts of garbage on the serial console - as if the baud rate is being periodically set to something weird, and then back to 112500. I see over a dozen blocks of junk interspersed with good output.

Is there any correlation of the garbage to printks of console enabled messages?

Quoted 2 lines

This in on ia64 with "console=uart,io,0x3f8" on the command line.

Does "console=ttyS0,115200" or "console=uart,io,0x3f8,115200" work?

You will need this fix for the 2nd one to work:

commit e26f1db9b8d74617519e50b41749900d0a257406

Author: Rob Herring <[email protected]>
Date:   Wed Apr 30 19:48:29 2014 -0500

tty/serial: fix generic earlycon option parsing

Rob

Quoted 11 lines

git bisect pointed me here:

d2fd6810a823bcde1ee232668f5689837aafa772 is first bad commit commit d2fd6810a823bcde1ee232668f5689837aafa772

Author: Rob Herring <[email protected]>
Date:   Fri Apr 18 17:19:56 2014 -0500

tty/serial: convert 8250 to generic earlycon

-Tony

#17 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

In reply to Rob Herring
Quoted 18 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)
drivers/tty/serial/8250/8250_early.c +0 -0
index c100d63..e83c9db 100644
@@ -35,18 +35,8 @@

...

drivers/tty/serial/8250/8250_early.c

Quoted 2 lines
drivers/tty/serial/8250/8250_early.c +0 -2
-
-int __init setup_early_serial8250_console(char *cmdline)

You removed global function, but still left declaration and calling...

arch/mips/mti-malta/malta-init.c:
setup_early_serial8250_console(console_string);
drivers/firmware/pcdp.c: return setup_early_serial8250_console(options);
include/linux/serial_8250.h:extern int
setup_early_serial8250_console(char *cmdline);

Yinghai

#18 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 25 lines · Yinghai Lu
Quoted 18 lines · Rob Herring

From: Rob Herring <[email protected]>

With the generic earlycon infrastructure in place, convert the 8250 early console to use it.

Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>
---
 drivers/tty/serial/8250/8250_early.c | 138 ++++-------------------------------
 drivers/tty/serial/8250/Kconfig      |   1 +
 2 files changed, 16 insertions(+), 123 deletions(-)
drivers/tty/serial/8250/8250_early.c +0 -0
index c100d63..e83c9db 100644
@@ -35,18 +35,8 @@

...

drivers/tty/serial/8250/8250_early.c

Quoted 2 lines
drivers/tty/serial/8250/8250_early.c +0 -2
-
-int __init setup_early_serial8250_console(char *cmdline)

You removed global function, but still left declaration and calling...

Quoted 5 lines

arch/mips/mti-malta/malta-init.c:
setup_early_serial8250_console(console_string);
drivers/firmware/pcdp.c: return setup_early_serial8250_console(options);
include/linux/serial_8250.h:extern int
setup_early_serial8250_console(char *cmdline);

Thanks for finding these. I missed them in my build tests. This should fix them:

(quoted diff) +0 -0

b/drivers/tty/serial/8250/8250_early.c
index e83c9db..2094c3b 100644

drivers/tty/serial/8250/8250_early.c +0 -0
@@ -156,6 +156,11 @@ static int __init early_serial8250_setup(struct

earlycon_device *device,
EARLYCON_DECLARE(uart8250, early_serial8250_setup); EARLYCON_DECLARE(uart, early_serial8250_setup);

+int __init setup_early_serial8250_console(char *cmdline) +{
+ return setup_earlycon(cmdline, "uart8250", early_serial8250_setup);
+}
+
int serial8250_find_port_for_earlycon(void)

 {
        struct earlycon_device *device = early_device;
#19 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 21 lines · Rob Herring

On Sat, Apr 26, 2014 at 1:29 AM, Yinghai Lu <[email protected]> wrote:

Thanks for finding these. I missed them in my build tests. This should fix them:

drivers/tty/serial/8250/8250_early.c +5 -0
index e83c9db..2094c3b 100644
@@ -156,6 +156,11 @@ static int __init early_serial8250_setup(struct
 earlycon_device *device,
 EARLYCON_DECLARE(uart8250, early_serial8250_setup);
 EARLYCON_DECLARE(uart, early_serial8250_setup);
 
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       return setup_earlycon(cmdline, "uart8250", early_serial8250_setup);
+}
+
 int serial8250_find_port_for_earlycon(void)
 {
Quoted 1 line
        struct earlycon_device *device = early_device;

that only handle "uart8250,", may need to add more lines to handle "uart,"

+int __init setup_early_serial8250_console(char *cmdline) +{

+       char *options;
+       options = strstr(cmdline, "uart8250,");
+       if (options)

+ return setup_earlycon(cmdline, "uart8250",
early_serial8250_setup);
+
+ options = strstr(cmdline, "uart,");
+ if (options)
+ return setup_earlycon(cmdline, "uart", early_serial8250_setup);
+
+ return 0;
+}
+

Thanks

Yinghai

#20 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 15 lines · Yinghai Lu
Quoted 14 lines · Rob Herring

On Sat, Apr 26, 2014 at 1:29 AM, Yinghai Lu <[email protected]> wrote:

Thanks for finding these. I missed them in my build tests. This should fix them:

drivers/tty/serial/8250/8250_early.c +0 -0
index e83c9db..2094c3b 100644
@@ -156,6 +156,11 @@ static int __init early_serial8250_setup(struct
 earlycon_device *device,
 EARLYCON_DECLARE(uart8250, early_serial8250_setup);
 EARLYCON_DECLARE(uart, early_serial8250_setup);
 
Quoted 10 lines
Quoted 8 lines
drivers/tty/serial/8250/8250_early.c +5 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       return setup_earlycon(cmdline, "uart8250", early_serial8250_setup);
+}
+
 int serial8250_find_port_for_earlycon(void)
 {
        struct earlycon_device *device = early_device;

that only handle "uart8250,", may need to add more lines to handle "uart,"

That is on purpose because the only 2 users use uart8250. I consider this a legacy interface and use of "uart" is horrible because there are lots of uarts which are not 8250.

Rob

Quoted 20 lines
(quoted diff) +6 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       char *options;
+       options = strstr(cmdline, "uart8250,");
+       if (options)
+               return setup_earlycon(cmdline, "uart8250",

early_serial8250_setup);

(quoted diff) +8 -0
+
+       options = strstr(cmdline, "uart,");
+       if (options)
+              return setup_earlycon(cmdline, "uart", early_serial8250_setup);
+
+      return 0;
+}
+

Thanks

Yinghai

#21 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 35 lines · Rob Herring
Quoted 15 lines · Yinghai Lu
Quoted 14 lines · Rob Herring

On Sat, Apr 26, 2014 at 1:29 AM, Yinghai Lu <[email protected]> wrote:

Thanks for finding these. I missed them in my build tests. This should fix them:

drivers/tty/serial/8250/8250_early.c +0 -0
index e83c9db..2094c3b 100644
@@ -156,6 +156,11 @@ static int __init early_serial8250_setup(struct
 earlycon_device *device,
 EARLYCON_DECLARE(uart8250, early_serial8250_setup);
 EARLYCON_DECLARE(uart, early_serial8250_setup);
 
Quoted 10 lines
Quoted 8 lines
drivers/tty/serial/8250/8250_early.c +5 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       return setup_earlycon(cmdline, "uart8250", early_serial8250_setup);
+}
+
 int serial8250_find_port_for_earlycon(void)
 {
        struct earlycon_device *device = early_device;

that only handle "uart8250,", may need to add more lines to handle "uart,"

That is on purpose because the only 2 users use uart8250. I consider this a legacy interface and use of "uart" is horrible because there are lots of uarts which are not 8250.

Rob

Quoted 1 line
Quoted 14 lines
Quoted 7 lines
(quoted diff) +6 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       char *options;
+       options = strstr(cmdline, "uart8250,");
+       if (options)
+               return setup_earlycon(cmdline, "uart8250",

early_serial8250_setup);

Review

Quoted 7 lines
(quoted diff) +7 -0
+
+       options = strstr(cmdline, "uart,");
+       if (options)
+              return setup_earlycon(cmdline, "uart", early_serial8250_setup);
+
+      return 0;
+}

You want to obsolete "console=uart,io,0x3f8,115200n8" ?

Let's check with Andrew. He suggested to use uart and uart8250 at that time.

Thanks

Yinghai

#22 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 53 lines · Yinghai Lu
Quoted 35 lines · Rob Herring
Quoted 15 lines · Yinghai Lu
Quoted 14 lines · Rob Herring

On Sat, Apr 26, 2014 at 1:29 AM, Yinghai Lu <[email protected]> wrote:

Thanks for finding these. I missed them in my build tests. This should fix them:

drivers/tty/serial/8250/8250_early.c +0 -0
index e83c9db..2094c3b 100644
@@ -156,6 +156,11 @@ static int __init early_serial8250_setup(struct
 earlycon_device *device,
 EARLYCON_DECLARE(uart8250, early_serial8250_setup);
 EARLYCON_DECLARE(uart, early_serial8250_setup);
 
Quoted 10 lines
Quoted 8 lines
drivers/tty/serial/8250/8250_early.c +5 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       return setup_earlycon(cmdline, "uart8250", early_serial8250_setup);
+}
+
 int serial8250_find_port_for_earlycon(void)
 {
        struct earlycon_device *device = early_device;

that only handle "uart8250,", may need to add more lines to handle "uart,"

That is on purpose because the only 2 users use uart8250. I consider this a legacy interface and use of "uart" is horrible because there are lots of uarts which are not 8250.

Rob

Quoted 1 line
Quoted 14 lines
Quoted 7 lines
(quoted diff) +6 -0
+int __init setup_early_serial8250_console(char *cmdline)
+{
+       char *options;
+       options = strstr(cmdline, "uart8250,");
+       if (options)
+               return setup_earlycon(cmdline, "uart8250",

early_serial8250_setup);

Review

Quoted 7 lines
(quoted diff) +7 -0
+
+       options = strstr(cmdline, "uart,");
+       if (options)
+              return setup_earlycon(cmdline, "uart", early_serial8250_setup);
+
+      return 0;
+}

You want to obsolete "console=uart,io,0x3f8,115200n8" ?

Quoted 1 line

Let's check with Andrew. He suggested to use uart and uart8250 at that time.

No, that is not what I'm saying. For the 2 callers of setup_early_serial8250_console which are crafting a console string from firmware data, they can and do use uart8250. I don't expect this mechanism for setting up early console to expand to other users. The whole point of this series is to allow any uart to be supported for earlycon. For anyone using the kernel command line, both uart and uart8250 are still supported.

Rob

#23 lore raw

Re: [PATCH v2 3/7] tty/serial: convert 8250 to generic earlycon

Quoted 6 lines · Rob Herring
Quoted 4 lines · Yinghai Lu

You want to obsolete "console=uart,io,0x3f8,115200n8" ?

Let's check with Andrew. He suggested to use uart and uart8250 at that time.

Quoted 7 lines

No, that is not what I'm saying. For the 2 callers of setup_early_serial8250_console which are crafting a console string from firmware data, they can and do use uart8250. I don't expect this mechanism for setting up early console to expand to other users. The whole point of this series is to allow any uart to be supported for earlycon. For anyone using the kernel command line, both uart and uart8250 are still supported.

That is confusing, why not keeping them consistent?

I posted one patch before about "early early console for x86", and it is in my local tree
for some time.support both "uart,io" and "uart8250,io".

Peter, Can you check that patch again? --- updated version attached. and inlined.

Thanks

Yinghai

Subject: [PATCH -v4] x86: Setup early console as early as possible in x86_start_kernel()

Analyze "console=uart8250,io,0x3f8,115200n8" in i386_start_kernel/x86_64_start_kernel,
and call setup_early_serial8250_console() to init early serial console.

Only can handle io port kind of 8250, because mmio need ioremap.

Use boot_params.hdr.version instead of adding another variable, Suggested by hpa.
Also need to apply this one after x86 memblock patchset.

---
 arch/x86/include/asm/setup.h |    2 ++
 arch/x86/kernel/head.c       |   26 ++++++++++++++++++++++++++
 arch/x86/kernel/head32.c     |    1 +
 arch/x86/kernel/head64.c     |    5 ++++-
 kernel/printk/printk.c       |   11 +++++++----
 5 files changed, 40 insertions(+), 5 deletions(-)
arch/x86/include/asm/setup.h +2 -0
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
@@ -49,6 +49,8 @@ static inline void x86_acpi_override_fin
 #endif
 
 extern unsigned long saved_video_mode;
+int setup_early_serial8250_console(char *cmdline);
+void setup_early_console(void);
 
 extern void reserve_standard_io_resources(void);
 extern void i386_reserve_resources(void);
arch/x86/kernel/head.c +26 -0
Index: linux-2.6/arch/x86/kernel/head.c
===================================================================
@@ -69,3 +69,29 @@ void __init reserve_ebda_region(void)
     /* reserve all memory between lowmem and the 1MB mark */
     memblock_reserve(lowmem, 0x100000 - lowmem);
 }
+
+void __init setup_early_console(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+    char constr[64], *p, *q;
+
+    /* Can not handle mmio type 8250 uart yet, too early */
+    p = strstr(boot_command_line, "console=uart8250,io,");
+    if (!p)
+        p = strstr(boot_command_line, "console=uart,io,");
+    if (!p)
+        return;
+
+    p += 8;    /* sizeof "console=" */
+    q = strchr(p, ' ');
+    if ((q - p) >= sizeof(constr))
+        return;
+
+    memset(constr, 0, sizeof(constr));
+    memcpy(constr, p, q - p);
+
+    lockdep_init();
+
+    setup_early_serial8250_console(constr);
+#endif
+}
arch/x86/kernel/head32.c +1 -0
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
@@ -32,6 +32,7 @@ static void __init i386_default_early_se
 void __init i386_start_kernel(void)
 {
     sanitize_boot_params(&boot_params);
+    setup_early_console();
 
     /* Call the subarch specific early setup function */
     switch (boot_params.hdr.hardware_subarch) {
arch/x86/kernel/head64.c +4 -1
Index: linux-2.6/arch/x86/kernel/head64.c
===================================================================
@@ -166,6 +166,7 @@ void __init x86_64_start_kernel(char * r
     load_idt((const struct desc_ptr *)&idt_descr);
 
     copy_bootdata(__va(real_mode_data));
+    setup_early_console();
 
     /*
      * Load microcode early on BSP.
@@ -187,8 +188,10 @@ void __init x86_64_start_kernel(char * r
 void __init x86_64_start_reservations(char *real_mode_data)
 {
     /* version is always not zero if it is copied */
-    if (!boot_params.hdr.version)
+    if (!boot_params.hdr.version) {
         copy_bootdata(__va(real_mode_data));
+        setup_early_console();
+    }
 
     reserve_ebda_region();
 
kernel/printk/printk.c +7 -4
Index: linux-2.6/kernel/printk/printk.c
===================================================================
@@ -2227,11 +2227,14 @@ void register_console(struct console *ne
     struct console_cmdline *c;
 
     if (console_drivers)
-        for_each_console(bcon)
-            if (WARN(bcon == newcon,
-                    "console '%s%d' already registered\n",
-                    bcon->name, bcon->index))
+        for_each_console(bcon) {
+            /* not again */
+            if (bcon == newcon) {
+                printk(KERN_INFO "console '%s%d' already registered\n",
+                    bcon->name, bcon->index);
                 return;
+            }
+    }
 
     /*
      * before we register a new CON_BOOT console, make sure we don't

-------------- next part --------------
A non-text attachment was scrubbed...
Name: setup_early_console_x1_pa_symbol_before_earlcon.patch
Type: text/x-patch
Size: 4105 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140429/f527c861/attachment.bin>

#24 lore raw

PATCH v2 4/7 tty/serial: pl011: add generic earlycon support

In reply to Rob Herring

From: Rob Herring <[email protected]>

Add earlycon support for the pl011 serial port. This allows enabling the pl011 for console when early_params are processed. This is based on the arm64 earlyprintk support and is intended to replace it.

Cc Russell King <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>

---
v2:
- Rework the kernel-parameters.txt description

 Documentation/kernel-parameters.txt |  7 +++++++
 drivers/tty/serial/Kconfig          |  1 +
 drivers/tty/serial/amba-pl011.c     | 30 +++++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 1 deletion(-)
Documentation/kernel-parameters.txt +7 -0
index 03e50b4..15b5fcca 100644
@@ -890,6 +890,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			which are not unmapped.
 
 	earlycon=	[KNL] Output early console device and options.
+
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
@@ -899,6 +900,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			(mmio) or 32-bit (mmio32).
 			The options are the same as for ttyS, above.
 
+		pl011,<addr>
+			Start an early, polled-mode console on a pl011 serial
+			port at the specified address. The pl011 serial port
+			must already be setup and configured. Options are not
+			yet supported.
+
 	earlyprintk=	[X86,SH,BLACKFIN,ARM]
 			earlyprintk=vga
 			earlyprintk=efi
drivers/tty/serial/Kconfig +1 -0
index 3b7c19b..b1b23c2 100644
@@ -60,6 +60,7 @@ config SERIAL_AMBA_PL011_CONSOLE
 	bool "Support for console on AMBA serial port"
 	depends on SERIAL_AMBA_PL011=y
 	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
 	---help---
 	  Say Y here if you wish to use an AMBA PrimeCell UART as the system
 	  console (the system console is the device which receives all kernel
drivers/tty/serial/amba-pl011.c +29 -1
index d4eda24..4227c0a 100644
@@ -303,7 +303,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
 
 	/* Optionally make use of an RX channel as well */
 	chan = dma_request_slave_channel(dev, "rx");
-	
+
 	if (!chan && plat->dma_rx_param) {
 		chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
 
@@ -2045,6 +2045,34 @@ static struct console amba_console = {
 };
 
 #define AMBA_CONSOLE	(&amba_console)
+
+static void pl011_putc(struct uart_port *port, int c)
+{
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+		;
+	writeb(c, port->membase + UART01x_DR);
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
+		;
+}
+
+static void pl011_early_write(struct console *con, const char *s, unsigned n)
+{
+	struct earlycon_device *dev = con->data;
+
+	uart_console_write(&dev->port, s, n, pl011_putc);
+}
+
+static int __init pl011_early_console_setup(struct earlycon_device *device,
+					    const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = pl011_early_write;
+	return 0;
+}
+EARLYCON_DECLARE(pl011, pl011_early_console_setup);
+
 #else
 #define AMBA_CONSOLE	NULL
 #endif
Signature · 1 line
1.9.1
#25 lore raw

PATCH v2 5/7 tty/serial: add arm/arm64 semihosting earlycon

In reply to Rob Herring

From: Rob Herring <[email protected]>

Add earlycon support for the arm/arm64 semihosting debug serial interface. This allows enabling a debug console when early_params are processed. This is based on the arm64 earlyprintk smh support and is intended to replace it.

Cc Greg Kroah-Hartman <[email protected]>
Cc Jiri Slaby <[email protected]>

---
v2:
- Add support for ARM32 semihosting
- Rework the kernel-parameters.txt description
- Update copyright per Catalin.

 Documentation/kernel-parameters.txt        |  2 +
 drivers/tty/serial/Kconfig                 | 10 +++++
 drivers/tty/serial/Makefile                |  1 +
 drivers/tty/serial/earlycon-arm-semihost.c | 61 ++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+)
 create mode 100644 drivers/tty/serial/earlycon-arm-semihost.c
Documentation/kernel-parameters.txt +2 -0
index 15b5fcca..9e9935a 100644
@@ -906,6 +906,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			must already be setup and configured. Options are not
 			yet supported.
 
+		smh	Use ARM semihosting calls for early console.
+
 	earlyprintk=	[X86,SH,BLACKFIN,ARM]
 			earlyprintk=vga
 			earlyprintk=efi
drivers/tty/serial/Kconfig +10 -0
index b1b23c2..8cce654 100644
@@ -73,6 +73,16 @@ config SERIAL_AMBA_PL011_CONSOLE
 	  your boot loader (lilo or loadlin) about how to pass options to the
 	  kernel at boot time.)
 
+config SERIAL_EARLYCON_ARM_SEMIHOST
+	bool "Early console using ARM semihosting"
+	depends on ARM64 || ARM
+	select SERIAL_EARLYCON
+	help
+	  Support for early debug console using ARM semihosting. This enables
+	  the console before standard serial driver is probed. This is enabled
+	  with "earlycon=smh" on the kernel command line. The console is
+	  enabled when early_param is processed.
+
 config SERIAL_SB1250_DUART
 	tristate "BCM1xxx on-chip DUART serial support"
 	depends on SIBYTE_SB1xxx_SOC=y
drivers/tty/serial/Makefile +1 -0
index 8af1415..9965b65 100644
@@ -6,6 +6,7 @@ obj-$(CONFIG_SERIAL_CORE) += serial_core.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
 obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
+obj-$(CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST) += earlycon-arm-semihost.o
 
 # These Sparc drivers have to appear before others such as 8250
 # which share ttySx minor node space.  Otherwise console device
drivers/tty/serial/earlycon-arm-semihost.c new file +61 -0

61 lines not on this page · raw message

Signature · 1 line
1.9.1
#26 lore raw

PATCH v2 6/7 arm64: enable FIX_EARLYCON_MEM kconfig

In reply to Rob Herring

From: Rob Herring <[email protected]>

In order to support earlycon on arm64, we need to enable earlycon fixmap support.

Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/Kconfig | 3 +++
 1 file changed, 3 insertions(+)
arch/arm64/Kconfig +3 -0
index e6e4d37..22d1397 100644
@@ -112,6 +112,9 @@ config IOMMU_HELPER
 config KERNEL_MODE_NEON
 	def_bool y
 
+config FIX_EARLYCON_MEM
+	def_bool y
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
Signature · 1 line
1.9.1
#27 lore raw

PATCH v2 7/7 arm64: remove arch specific earlyprintk

In reply to Rob Herring

From: Rob Herring <[email protected]>

Now that we have equivalent earlycon support, arm64's earlyprintk code can be removed.

Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/Kconfig.debug         |   9 ---
 arch/arm64/kernel/Makefile       |   1 -
 arch/arm64/kernel/early_printk.c | 158 ---------------------------------------
 3 files changed, 168 deletions(-)
 delete mode 100644 arch/arm64/kernel/early_printk.c
arch/arm64/Kconfig.debug +0 -9
index d10ec33..1c1b756 100644
@@ -20,15 +20,6 @@ config STRICT_DEVMEM
 
 	  If in doubt, say Y.
 
-config EARLY_PRINTK
-	bool "Early printk support"
-	default y
-	help
-	  Say Y here if you want to have an early console using the
-	  earlyprintk=<name>[,<addr>][,<options>] kernel parameter. It
-	  is assumed that the early console device has been initialised
-	  by the boot loader prior to starting the Linux kernel.
-
 config PID_IN_CONTEXTIDR
 	bool "Write the current PID to the CONTEXTIDR register"
 	help
arch/arm64/kernel/Makefile +0 -1
index 7d811d9..7a6fce5 100644
@@ -18,7 +18,6 @@ arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
-arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
arch/arm64/kernel/early_printk.c deleted +0 -158

158 lines not on this page · raw message

Signature · 1 line
1.9.1
maintainer Acked-by on the v2 series
#28 lore raw
In reply to Rob Herring
Quoted 8 lines · Rob Herring

Rob Herring (7):
x86: move FIX_EARLYCON_MEM kconfig into x86
tty/serial: add generic serial earlycon
tty/serial: convert 8250 to generic earlycon
tty/serial: pl011: add generic earlycon support
tty/serial: add arm/arm64 semihosting earlycon
arm64: enable FIX_EARLYCON_MEM kconfig
arm64: remove arch specific earlyprintk

The series looks fine, you can add:

BTW, are you merging all of them via some other tree or would prefer me to take the arm64-specific patches?

#29 lore raw
Quoted 10 lines · Catalin Marinas
Quoted 8 lines · Rob Herring

Rob Herring (7):
x86: move FIX_EARLYCON_MEM kconfig into x86
tty/serial: add generic serial earlycon
tty/serial: convert 8250 to generic earlycon
tty/serial: pl011: add generic earlycon support
tty/serial: add arm/arm64 semihosting earlycon
arm64: enable FIX_EARLYCON_MEM kconfig
arm64: remove arch specific earlyprintk

Quoted 4 lines

The series looks fine, you can add:

Thanks.

Quoted 2 lines

BTW, are you merging all of them via some other tree or would prefer me to take the arm64-specific patches?

Greg has taken it, but there were a few issues, so it may get reposted.

Rob