Skip to contentSkip to conversation

ACPI: DBGP/DBG2 early console support for LPIA.

PATCH Superseded Lv Zheng 8 participants 35 messages Sep 27, 2012 – Jun 4, 2013 1 message not in the archive

Subsystems (5)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Lv Zheng

author
#1 lore raw

v4 cover ACPI: DBGP/DBG2 early console support for LPIA.

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
Recent Low Power Intel Architecture (LPIA) platforms have utilized this for the SPI UART debug ports that are resident on their debug boards.

This patch set enables the DBGP/DBG2 debug ports as an Linux early console launcher.
The SPI UART debug ports support is also refined to co-exist with this new usage model.

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

Version 3 of this patch set is the first version that will be published in the Linux community. Earlier versions are reviewed internally in Intel. This patch set keeps the version number to track the history that is known to Intel internal developers.

Lv Zheng (2):
ACPI: Add early console framework for DBGP/DBG2.
ACPI: Add Intel MID SPI early console support.

 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   25 ++++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/acpi/boot.c                |    1 +
 arch/x86/kernel/early_printk.c             |   25 +++-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/acpi/Makefile                      |    2 +
 drivers/acpi/early_printk.c                |  201 +++++++++++++++++++++++++
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/acpi.h                       |   24 +++
 include/linux/intel_mid_early.h            |   12 ++
 14 files changed, 526 insertions(+), 181 deletions(-)
 create mode 100644 drivers/acpi/early_printk.c
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Signature · 1 line
1.7.10
author
#2 lore raw

PATCH v4 1/2 ACPI: Add early console framework for DBGP/DBG2.

Microsoft Debug Port Table (DBGP or DBG2) is required for Windows SoC platforms. This patch is introduced to fix the gap between Windows and Linux.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  201 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   24 +++++
 7 files changed, 257 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================
@@ -763,6 +763,7 @@
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -59,6 +59,21 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
Index: linux-acpi/arch/x86/kernel/acpi/boot.c
===================================================================
@@ -1518,6 +1518,7 @@
 		return;
 	}
 
+	acpi_early_console_parse();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -200,6 +200,15 @@
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init acpi_early_console_setup(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_init(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
Index: linux-acpi/drivers/acpi/Makefile
===================================================================
@@ -46,6 +46,8 @@
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +201 -0

201 lines not on this page · raw message

include/linux/acpi.h +24 -0
Index: linux-acpi/include/linux/acpi.h
===================================================================
@@ -430,4 +430,28 @@
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+typedef int (*acpi_early_console_handler)(struct acpi_debug_port *dev,
+					  const unsigned long end);
+
+int __init acpi_early_console_keep(void);
+int __init acpi_early_console_init(char *s, int keep);
+int __init acpi_early_console_parse(void);
+int __init acpi_early_console_setup(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_parse(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
#3 lore raw

Re: [PATCH v3 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 125 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is required for Windows SoC platforms. This patch is introduced to fix the gap between Windows and Linux.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  201 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   24 +++++
 7 files changed, 257 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c

Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================

Documentation/kernel-parameters.txt +1 -0
@@ -763,6 +763,7 @@
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.

Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================

arch/x86/Kconfig.debug +15 -0
@@ -59,6 +59,21 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL

Index: linux-acpi/arch/x86/kernel/acpi/boot.c
===================================================================

arch/x86/kernel/acpi/boot.c +1 -0
@@ -1518,6 +1518,7 @@
 		return;
 	}
 
+	acpi_early_console_parse();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*

Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================

arch/x86/kernel/early_printk.c +13 -0
@@ -200,6 +200,15 @@
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init acpi_early_console_setup(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_init(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);

Index: linux-acpi/drivers/acpi/Makefile
===================================================================

drivers/acpi/Makefile +2 -0
@@ -46,6 +46,8 @@
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o

Index: linux-acpi/drivers/acpi/early_printk.c
===================================================================

drivers/acpi/early_printk.c new file +10 -0
@@ -0,0 +1,201 @@
+/*
+ *  acpi/early_printk.c - ACPI Boot-Time Debug Ports
+ *
+ *  Copyright (C) 2012 Lv Zheng <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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

drivers/acpi/early_printk.c line 20

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Please remove the address.

Quoted 27 lines
drivers/acpi/early_printk.c new file +27 -0
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/bootmem.h>
+
+#define ACPI_EARLY_DISABLED	0x0000
+#define ACPI_EARLY_ENABLED	0x0001
+#define ACPI_EARLY_KEEP		0x0002
+#define ACPI_EARLY_PORT_MSK	0xFF00
+#define ACPI_EARLY_PORT_OFF	8
+
+u16 acpi_early_flags = ACPI_EARLY_DISABLED;
+
+static inline bool acpi_early_enabled(void)
+{
+	return acpi_early_flags & ACPI_EARLY_ENABLED;
+}
+
+static inline u8 acpi_early_port_index(void)

drivers/acpi/early_printk.c line 57

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+{
+	return (acpi_early_flags & ACPI_EARLY_PORT_MSK) >> ACPI_EARLY_PORT_OFF;
+}
+
+int __init acpi_early_console_keep(void)
+{
+	return acpi_early_flags & ACPI_EARLY_KEEP ? 1 : 0;
+}
+
+static inline int acpi_table_parse_dbg2(acpi_early_console_handler handler)

Why inline?

And somehow I am not able to find acpi_early_console_handler?

Quoted 8 lines
drivers/acpi/early_printk.c new file +8 -0
+{
+	struct acpi_table_header *table_header = NULL;
+	struct acpi_dbg2_device *entry;
+	unsigned int count = 0;
+	unsigned long table_end;
+	acpi_size tbl_size;
+	unsigned int max_entries;
+	struct acpi_debug_port devinfo;

drivers/acpi/early_printk.c line 75

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (!handler)
+		return -EINVAL;
+
+	acpi_get_table(ACPI_SIG_DBG2, 0, &table_header);
+	if (!table_header) {
+		pr_warn("DBG2 not present\n");

Um, pr_warn in an early printk driver? Perhaps pr_debug?

Quoted 23 lines
drivers/acpi/early_printk.c new file +23 -0
+		return -ENODEV;
+	}
+	tbl_size = table_header->length;
+	table_end = (unsigned long)table_header + table_header->length;
+
+	entry = (struct acpi_dbg2_device *)
+	    ((unsigned long)table_header +
+	     ((struct acpi_table_dbg2 *)table_header)->info_offset);
+	max_entries = ((struct acpi_table_dbg2 *)table_header)->info_count;
+
+	while (((unsigned long)entry) + sizeof(struct acpi_dbg2_device) <
+	       table_end) {
+		if (entry->revision != 0) {
+			pr_warn("DBG2 revision %d not supported\n",
+				entry->revision);
+			count = -ENODEV;
+			goto fail;
+		}
+		if (!max_entries || count++ < max_entries) {
+			devinfo.port_index = (u8)count;
+			devinfo.port_type = entry->port_type;
+			devinfo.port_subtype = entry->port_subtype;
+			devinfo.register_count = entry->register_count;

drivers/acpi/early_printk.c line 108

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+			devinfo.registers = (struct acpi_generic_address *)
+			    ((unsigned long)entry + entry->base_address_offset);
+			devinfo.namepath_length = entry->namepath_length;
+			devinfo.namepath = (char *)
+			    ((unsigned long)entry + entry->namepath_offset);
+			devinfo.oem_data_length = entry->oem_data_length;
+			devinfo.oem_data = (u8 *)
+			    ((unsigned long)entry + entry->oem_data_offset);
+
+			if (handler(&devinfo, table_end)) {

Oh! it is a function! Perhaps call it 'func' or just use the raw decleration in the arguments instead of using a typedef.

Quoted 9 lines
drivers/acpi/early_printk.c new file +9 -0
+				count = -ENODEV;
+				goto fail;
+			}
+		}
+
+		entry = (struct acpi_dbg2_device *)
+		    ((unsigned long)entry + entry->length);
+	}
+

drivers/acpi/early_printk.c line 127

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+fail:
+	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+	return count;
+}
+
+static int __init acpi_parse_early_console(struct acpi_debug_port *info,
+					   const unsigned long end)
+{
+	pr_info("early: DBG2 console %d detected: %04x:%04x.\n",
+		info->port_index, info->port_type, info->port_subtype);

Um, pr_info in a earlyconsole driver? Perhaps it should be pr_debug

Quoted 112 lines
drivers/acpi/early_printk.c new file +74 -0
+
+	if (acpi_early_port_index() != 0 &&
+	    acpi_early_port_index() != info->port_index)
+		return 0;
+
+	acpi_early_console_setup(info);
+
+	return 0;
+}
+
+static int __init acpi_parse_dbgp(struct acpi_table_header *table)
+{
+	struct acpi_table_dbgp *dbgp;
+	struct acpi_debug_port devinfo;
+
+	if (acpi_early_port_index() != 0 &&
+	    acpi_early_port_index() != 1)
+		return 0;
+
+	dbgp = (struct acpi_table_dbgp *)table;
+	if (!dbgp) {
+		pr_warn("Unable to map DBGP\n");
+		return -ENODEV;
+	}
+
+	pr_info("early: DBGP console detected: %04x.\n",
+		dbgp->type);
+
+	devinfo.port_index = 1;
+	devinfo.port_type = ACPI_DBG2_SERIAL_PORT;
+	devinfo.port_subtype = dbgp->type;
+	devinfo.register_count = 1;
+	devinfo.registers = (struct acpi_generic_address *)&dbgp->debug_port;
+	devinfo.namepath_length = 0;
+	devinfo.namepath = NULL;
+	devinfo.oem_data_length = 0;
+	devinfo.oem_data = NULL;
+
+	acpi_parse_early_console(&devinfo, 0);
+
+	return 0;
+}
+
+int __init acpi_early_console_parse(void)
+{
+	if (!acpi_early_enabled())
+		return -EINVAL;
+
+	if (acpi_table_parse_dbg2(acpi_parse_early_console) == 0)
+		acpi_table_parse(ACPI_SIG_DBGP, acpi_parse_dbgp);
+
+	return 0;
+}
+
+int __init acpi_early_console_init(char *s, int keep)
+{
+	char *e;
+
+	acpi_early_flags = ACPI_EARLY_ENABLED;
+	if (keep)
+		acpi_early_flags |= ACPI_EARLY_KEEP;
+
+	if (*s) {
+		u8 port;
+
+		port = (u8)simple_strtoul(s, &e, 10);
+		acpi_early_flags |= (port) << ACPI_EARLY_PORT_OFF;
+	}
+
+	pr_info("early: debug port index %d.\n", acpi_early_port_index());
+
+	return 0;
+}
+

Index: linux-acpi/include/linux/acpi.h
===================================================================

include/linux/acpi.h +24 -1
@@ -430,4 +430,28 @@
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+typedef int (*acpi_early_console_handler)(struct acpi_debug_port *dev,
+					  const unsigned long end);
+
+int __init acpi_early_console_keep(void);
+int __init acpi_early_console_init(char *s, int keep);
+int __init acpi_early_console_parse(void);
+int __init acpi_early_console_setup(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_parse(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
--

To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#4 lore raw

RE: [PATCH v3 1/2] ACPI: Add early console framework for DBGP/DBG2.

Hi,

This is my first time sending patch to the community, thanks for your suggestion.

Quoted 3 lines
Quoted 2 lines

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA

Please remove the address.

Done.

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+static inline int acpi_table_parse_dbg2(acpi_early_console_handler
+handler)

Why inline?

Done.
I was trying to eliminate ABI related callee/caller side generation as this function will be called only once. According to your suggestion, I removed the inline to make it a symbol.

Quoted 1 line

And somehow I am not able to find acpi_early_console_handler?

It's in the header file along with other acpi table handlers.

Quoted 2 lines

drivers/acpi/early_printk.c line 75

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+		pr_warn("DBG2 not present\n");

Um, pr_warn in an early printk driver? Perhaps pr_debug?

Done.

Quoted 4 lines

drivers/acpi/early_printk.c line 108

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+			if (handler(&devinfo, table_end)) {

Oh! it is a function! Perhaps call it 'func' or just use the raw decleration in the arguments instead of using a typedef.

This remains unmodified to keep the same style with other acpi table handlers.

Quoted 2 lines

drivers/acpi/early_printk.c line 127

Quoted 2 lines
drivers/acpi/early_printk.c new file +2 -0
+	pr_info("early: DBG2 console %d detected: %04x:%04x.\n",
+		info->port_index, info->port_type, info->port_subtype);

Done.

Best regards/Lv Zheng

#5 lore raw

Re: [PATCH v3 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 21 lines · Lv

Hi,

This is my first time sending patch to the community, thanks for your suggestion.

Quoted 3 lines
Quoted 2 lines

+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA

Please remove the address.

Done.

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+static inline int acpi_table_parse_dbg2(acpi_early_console_handler
+handler)

Why inline?

Done.
I was trying to eliminate ABI related callee/caller side generation as this function will be called only once. According to your suggestion, I removed the inline to make it a symbol.

Quoted 1 line

And somehow I am not able to find acpi_early_console_handler?

It's in the header file along with other acpi table handlers.

Quoted 2 lines

drivers/acpi/early_printk.c line 75

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+		pr_warn("DBG2 not present\n");

Um, pr_warn in an early printk driver? Perhaps pr_debug?

Quoted 7 lines

Done.

Quoted 4 lines

drivers/acpi/early_printk.c line 108

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+			if (handler(&devinfo, table_end)) {

Oh! it is a function! Perhaps call it 'func' or just use the raw decleration in the arguments instead of using a typedef.

This remains unmodified to keep the same style with other acpi table handlers.

OK. Perhaps a different name then? 'fnc_handler' ?

Quoted 7 lines
Quoted 3 lines

drivers/acpi/early_printk.c line 127

Quoted 3 lines
drivers/acpi/early_printk.c new file +2 -0
+	pr_info("early: DBG2 console %d detected: %04x:%04x.\n",
+		info->port_index, info->port_type, info->port_subtype);

Done.

Best regards/Lv Zheng

author
#6 lore raw

PATCH RESEND v4 1/2 ACPI: Add early console framework for DBGP/DBG2.

In reply to Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is required for Windows SoC platforms. This patch is introduced to fix the gap between Windows and Linux.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  201 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   24 +++++
 7 files changed, 257 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================
@@ -763,6 +763,7 @@
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -59,6 +59,21 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
Index: linux-acpi/arch/x86/kernel/acpi/boot.c
===================================================================
@@ -1518,6 +1518,7 @@
 		return;
 	}
 
+	acpi_early_console_parse();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -200,6 +200,15 @@
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init acpi_early_console_setup(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_init(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
Index: linux-acpi/drivers/acpi/Makefile
===================================================================
@@ -46,6 +46,8 @@
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +201 -0

201 lines not on this page · raw message

include/linux/acpi.h +24 -0
Index: linux-acpi/include/linux/acpi.h
===================================================================
@@ -430,4 +430,28 @@
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+typedef int (*acpi_early_console_handler)(struct acpi_debug_port *dev,
+					  const unsigned long end);
+
+int __init acpi_early_console_keep(void);
+int __init acpi_early_console_init(char *s, int keep);
+int __init acpi_early_console_parse(void);
+int __init acpi_early_console_setup(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_parse(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
author
#7 lore raw
In reply to Lv Zheng

Forgot to Cc x86 maintainers, will send again. Sorry for the noise.

Quoted 159 lines

-----Original Message-----
From: Zheng, Lv
Sent: Friday, September 28, 2012 10:40 AM
To: Brown, Len
Cc: [email protected]; [email protected]; Zheng, Lv
Subject: [PATCH v4 0/2] ACPI: DBGP/DBG2 early console support for LPIA.

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
Recent Low Power Intel Architecture (LPIA) platforms have utilized this for the SPI UART debug ports that are resident on their debug boards.

This patch set enables the DBGP/DBG2 debug ports as an Linux early console launcher.
The SPI UART debug ports support is also refined to co-exist with this new usage model.

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI
DBGP/DBG2
tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the console available to output messages. Since early consoles are always used for kernel boot up debugging, this must be done as early as possible to arm the kernel with more testability the kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK
START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which requires early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK
START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. As far as I know, one kind of issue might be found in EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]>.
2. Modifying above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK
START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose some debuggabilities in the kernel boot up. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementation need to be modified to split their initialization codes into tow part:
1. Detecting hardware. This can be called in the PROBE stage.
2. Applying user parameters. This can be called in the SETUP stage. Individual early console drver maintainers need to be involved to avoid regressions that might occur on this modification as the maintainers might offer the real tests rather than I can do.
3. Introducing a barely new debugging facility that does not relate to the current early console implementation to allow automatic detection for the early consoles.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   Early consoles started in this style will lose some debuggabilities in
   the kernel boot up.  If the system does not crash very early,
   developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Note that the user configuration can not be applied to the registered
   early consoles in this way as the acpi_table_init() is still called
   after the parse_early_param().  Instead, the early consoles should
   derive the hardware settings used in the BIOS/bootloaders.
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI is still need to be enabled along
   along with the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence looks like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+    +-----------------+
                            | ACPI DBGP LAUNCH   | -> | ACPI DBGP
PROBE | ->
                            +--------------------+    +-----------------+
      +--------------------+
   -> | EARLY_RPINTK START |
      +--------------------+

Version 3 of this patch set is the first version that will be published in the Linux community. Earlier versions are reviewed internally in Intel. This patch set keeps the version number to track the history that is known to Intel internal developers.
Version 4 of this patch set fixed bunch of CodingStyle issues.

Lv Zheng (2):
ACPI: Add early console framework for DBGP/DBG2.
ACPI: Add Intel MID SPI early console support.

 Documentation/kernel-parameters.txt        |    2 +
 arch/x86/Kconfig.debug                     |   38 +++++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/acpi/boot.c                |    1 +
 arch/x86/kernel/early_printk.c             |   25 +++-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/acpi/Makefile                      |    2 +
 drivers/acpi/early_printk.c                |  201
+++++++++++++++++++++++++
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220
++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/acpi.h                       |   24 +++
 include/linux/intel_mid_early.h            |   12 ++
 14 files changed, 540 insertions(+), 181 deletions(-)
 create mode 100644 drivers/acpi/early_printk.c
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h

--
1.7.10

author
#8 lore raw

PATCH RESEND v4 1/2 ACPI: Add early console framework for DBGP/DBG2.

In reply to Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is required for Windows SoC platforms. This patch is introduced to fix the gap between Windows and Linux.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  201 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   24 +++++
 7 files changed, 257 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================
@@ -763,6 +763,7 @@
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -59,6 +59,21 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
Index: linux-acpi/arch/x86/kernel/acpi/boot.c
===================================================================
@@ -1518,6 +1518,7 @@
 		return;
 	}
 
+	acpi_early_console_parse();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -200,6 +200,15 @@
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init acpi_early_console_setup(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_init(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
Index: linux-acpi/drivers/acpi/Makefile
===================================================================
@@ -46,6 +46,8 @@
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +201 -0

201 lines not on this page · raw message

include/linux/acpi.h +24 -0
Index: linux-acpi/include/linux/acpi.h
===================================================================
@@ -430,4 +430,28 @@
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+typedef int (*acpi_early_console_handler)(struct acpi_debug_port *dev,
+					  const unsigned long end);
+
+int __init acpi_early_console_keep(void);
+int __init acpi_early_console_init(char *s, int keep);
+int __init acpi_early_console_parse(void);
+int __init acpi_early_console_setup(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_parse(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
author
#9 lore raw

PATCH v4 2/2 ACPI: Add Intel MID SPI early console support.

In reply to Lv Zheng

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

---
 arch/x86/Kconfig.debug                     |   10 ++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 9 files changed, 269 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
arch/x86/Kconfig.debug +10 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -43,9 +43,19 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
Index: linux-acpi/arch/x86/include/asm/mrst.h
===================================================================
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +11 -1
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -205,6 +205,16 @@
 
 int __init acpi_early_console_setup(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep());
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179

214 lines not on this page · raw message

drivers/platform/x86/Makefile +2 -0
Index: linux-acpi/drivers/platform/x86/Makefile
===================================================================
@@ -50,3 +50,5 @@
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
Index: linux-acpi/drivers/platform/x86/early/Makefile
===================================================================
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0

220 lines not on this page · raw message

include/acpi/actbl2.h +1 -0
Index: linux-acpi/include/acpi/actbl2.h
===================================================================
@@ -341,6 +341,7 @@
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
Index: linux-acpi/include/linux/intel_mid_early.h
===================================================================
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
author
#10 lore raw

PATCH RESEND v4 2/2 ACPI: Add Intel MID SPI early console support.

In reply to Lv Zheng

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

---
 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   23 +++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
arch/x86/Kconfig.debug +23 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -43,9 +43,32 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.  This option does not introduce actual early console into
+	  the kernel binary, but is required by a real early console
+	  implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+	  You should normally N here unless you need to do kernel booting
+	  development.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are always equipped with SPI debug ports and
+	  USB OTG debug ports. To enable these debugging facilities, you
+	  need to pass "earlyprintk=mrst" parameter to the kernel through
+	  boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+	  details.  You should normally N here unless you need to do kernel
+	  booting development.
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
Index: linux-acpi/arch/x86/include/asm/mrst.h
===================================================================
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +11 -1
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -205,6 +205,16 @@
 
 int __init acpi_early_console_setup(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep());
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179

214 lines not on this page · raw message

drivers/platform/x86/Makefile +2 -0
Index: linux-acpi/drivers/platform/x86/Makefile
===================================================================
@@ -50,3 +50,5 @@
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
Index: linux-acpi/drivers/platform/x86/early/Makefile
===================================================================
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0

220 lines not on this page · raw message

include/acpi/actbl2.h +1 -0
Index: linux-acpi/include/acpi/actbl2.h
===================================================================
@@ -341,6 +341,7 @@
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
Index: linux-acpi/include/linux/intel_mid_early.h
===================================================================
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
Documentation/kernel-parameters.txt +1 -0
Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================
@@ -762,6 +762,7 @@
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
+			earlyprintk=mrst
 			earlyprintk=dbgp[debugController#]
 			earlyprintk=acpi[debugController#]
 
author
#11 lore raw

PATCH RESEND v4 2/2 ACPI: Add Intel MID SPI early console support.

In reply to Lv Zheng

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

---
 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   23 +++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
arch/x86/Kconfig.debug +23 -0
Index: linux-acpi/arch/x86/Kconfig.debug
===================================================================
@@ -43,9 +43,32 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.  This option does not introduce actual early console into
+	  the kernel binary, but is required by a real early console
+	  implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+	  You should normally N here unless you need to do kernel booting
+	  development.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are always equipped with SPI debug ports and
+	  USB OTG debug ports. To enable these debugging facilities, you
+	  need to pass "earlyprintk=mrst" parameter to the kernel through
+	  boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+	  details.  You should normally N here unless you need to do kernel
+	  booting development.
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
Index: linux-acpi/arch/x86/include/asm/mrst.h
===================================================================
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +11 -1
Index: linux-acpi/arch/x86/kernel/early_printk.c
===================================================================
@@ -205,6 +205,16 @@
 
 int __init acpi_early_console_setup(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep());
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179

214 lines not on this page · raw message

drivers/platform/x86/Makefile +2 -0
Index: linux-acpi/drivers/platform/x86/Makefile
===================================================================
@@ -50,3 +50,5 @@
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
Index: linux-acpi/drivers/platform/x86/early/Makefile
===================================================================
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0

220 lines not on this page · raw message

include/acpi/actbl2.h +1 -0
Index: linux-acpi/include/acpi/actbl2.h
===================================================================
@@ -341,6 +341,7 @@
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
Index: linux-acpi/include/linux/intel_mid_early.h
===================================================================
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
Documentation/kernel-parameters.txt +1 -0
Index: linux-acpi/Documentation/kernel-parameters.txt
===================================================================
@@ -762,6 +762,7 @@
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
+			earlyprintk=mrst
 			earlyprintk=dbgp[debugController#]
 			earlyprintk=acpi[debugController#]
 
#12 lore raw
In reply to Lv Zheng
Quoted 10 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
Recent Low Power Intel Architecture (LPIA) platforms have utilized this for the SPI UART debug ports that are resident on their debug boards.

This patch set enables the DBGP/DBG2 debug ports as an Linux early console launcher.
The SPI UART debug ports support is also refined to co-exist with this new usage model.

Hi Len,

You want to take this, or should I?

-hpa

Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.
reviewer
#13 lore raw
Quoted 2 lines

You want to take this, or should I?

go ahead and take the series in tip 3.8, Peter, thanks.

I looked over this series a while back and my feedback was that it should be disabled by default and enabled by bootparam -- like other earlyprink -- else an issue here would render a system un-bootable. I see that LV has addressed that in the latest version.

LV,
have you addressed the feedback from Konrad?

thanks,
-Len

#14 lore raw
Quoted 5 lines · Len Brown
Quoted 2 lines

You want to take this, or should I?

go ahead and take the series in tip 3.8, Peter, thanks.

I'll pull it in after the merge window closes and I get back home.

-hpa

author
#15 lore raw
In reply to Len Brown
Quoted 8 lines

go ahead and take the series in tip 3.8, Peter, thanks.

I looked over this series a while back and my feedback was that it should be disabled by default and enabled by bootparam -- like other earlyprink -- else an issue here would render a system un-bootable. I see that LV has addressed that in the latest version.
LV,
have you addressed the feedback from Konrad?

I missed the mail from Konrad. Thanks for your reminder. I'll find it and update my patches according to his suggestion.

Best regards/Lv Zheng

author
#16 lore raw

PATCH v6 1/2 ACPI: Add early console framework for DBGP/DBG2.

In reply to Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

This patch enables the DBGP/DBG2 debug ports as Linux early console launcher. Individual early console drivers are also needed to get the early kernel messages dumped on the consoles. For example, to use the SPI UART early console for the Low Power Intel Architecture (LPIA) platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.
There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 1:
1. Enables single DBG2 debug port support.
Version 2:
1. Applies Rui's comments.
Version 3:
1. Applies Len's comments (earlycon should be disabled by default).
2. Enables single DBG2 debug ports support.
Version 4:
1. Fixes the CodingStyle issues reported by checkpatch.pl.
2. Enables single DBGP debug port support.
Version 5:
1. Enables multiple DBG2 debug ports support.
2. Applies Konrad's comments (pr_debug should be used in earlycon).
3. Changes kstrtoul back to simple_strtoul.
Version 6:
1. Applies Konrad's comments (MAX_ACPI_DBG_PORTS bug and count improvement)
2. Adds "__init" and "__initdata" to the symbols introduced in this patch.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in the x86 specific booting codes. The kstrtoul will return error on strings like "acpi0,keep". This will leave one CodingStyle issue reported by the checkpatch.pl.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  172 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   22 +++++
 7 files changed, 226 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
index ad7e2e5..f656765 100644
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
index b322f12..5778082 100644
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
index b2297e5..cc10ea5 100644
@@ -1518,6 +1518,7 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 
+	acpi_early_console_probe();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
index 9b9f18b..bf5b596 100644
@@ -200,6 +200,15 @@ static inline void early_console_register(struct console *con, int keep_early)
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init __acpi_early_console_start(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@ static int __init setup_early_printk(char *buf)
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_launch(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
index 47199e2..99dbd64 100644
@@ -46,6 +46,8 @@ ifdef CONFIG_ACPI_VIDEO
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +172 -0

172 lines not on this page · raw message

include/linux/acpi.h +22 -0
index 4f2a762..641366c 100644
@@ -430,4 +430,26 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info);
+int __init acpi_early_console_launch(char *s, int keep);
+int __init acpi_early_console_probe(void);
+/* This interface is arch specific. */
+int __init __acpi_early_console_start(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_probe(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
Signature · 1 line
1.7.10
#17 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 269 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

This patch enables the DBGP/DBG2 debug ports as Linux early console launcher. Individual early console drivers are also needed to get the early kernel messages dumped on the consoles. For example, to use the SPI UART early console for the Low Power Intel Architecture (LPIA) platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.
There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 1:
1. Enables single DBG2 debug port support.
Version 2:
1. Applies Rui's comments.
Version 3:
1. Applies Len's comments (earlycon should be disabled by default).
2. Enables single DBG2 debug ports support.
Version 4:
1. Fixes the CodingStyle issues reported by checkpatch.pl.
2. Enables single DBGP debug port support.
Version 5:
1. Enables multiple DBG2 debug ports support.
2. Applies Konrad's comments (pr_debug should be used in earlycon).
3. Changes kstrtoul back to simple_strtoul.
Version 6:
1. Applies Konrad's comments (MAX_ACPI_DBG_PORTS bug and count improvement)
2. Adds "__init" and "__initdata" to the symbols introduced in this patch.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in the x86 specific booting codes. The kstrtoul will return error on strings like "acpi0,keep". This will leave one CodingStyle issue reported by the checkpatch.pl.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  172 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   22 +++++
 7 files changed, 226 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
index ad7e2e5..f656765 100644
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
index b322f12..5778082 100644
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
index b2297e5..cc10ea5 100644
@@ -1518,6 +1518,7 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 
+	acpi_early_console_probe();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
index 9b9f18b..bf5b596 100644
@@ -200,6 +200,15 @@ static inline void early_console_register(struct console *con, int keep_early)
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init __acpi_early_console_start(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@ static int __init setup_early_printk(char *buf)
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_launch(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
index 47199e2..99dbd64 100644
@@ -46,6 +46,8 @@ ifdef CONFIG_ACPI_VIDEO
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +17 -0
new file mode 100644
index 0000000..32b3c13
@@ -0,0 +1,172 @@
+/*
+ * acpi/early_printk.c - ACPI Boot-Time Debug Ports
+ *
+ * Copyright (c) 2012, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * 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; version 2
+ * of the License.
+ */
+
+#define DEBUG
+#define pr_fmt(fmt)	"ACPI: " KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>

drivers/acpi/early_printk.c line 27

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/bitmap.h>
+#include <linux/bootmem.h>
+
+#define MAX_ACPI_DBG_PORTS	16
+
+static __initdata DECLARE_BITMAP(acpi_early_flags, MAX_ACPI_DBG_PORTS*2);

So the __initdata means that this structure is going away when user-space launches. Is that OK if the user also supplied 'keep'?

drivers/acpi/early_printk.c line 37

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+static __initdata bool acpi_early_enabled;
+
+static int __init acpi_early_console_enable(u8 port, int keep)
+{
+	if (port >= MAX_ACPI_DBG_PORTS)
+		return -ENODEV;
+
+	set_bit(port, acpi_early_flags);
+	if (keep)
+		set_bit(port+MAX_ACPI_DBG_PORTS, acpi_early_flags);

Put a comment explaining why you use half of the bitmap to mark them as 'keep'. Thought wouldn't be just easier if you had another bitmap:

acpi_keep_ports?

To set those instead of using this bitmap?

Quoted 175 lines
drivers/acpi/early_printk.c new file +135 -0
+	acpi_early_enabled = true;
+
+	pr_debug("DBGx LAUNCH - console %d.\n", port);
+
+	return 0;
+}
+
+static bool __init acpi_early_console_enabled(u8 port)
+{
+	BUG_ON(port >= MAX_ACPI_DBG_PORTS);
+	return test_bit(port, acpi_early_flags);
+}
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info)
+{
+	BUG_ON(!info || info->port_index >= MAX_ACPI_DBG_PORTS);
+	return test_bit(info->port_index+MAX_ACPI_DBG_PORTS, acpi_early_flags);
+}
+
+static int __init acpi_early_console_start(struct acpi_debug_port *info)
+{
+	if (!acpi_early_console_enabled(info->port_index))
+		return 0;
+
+	pr_debug("DBGx START - console %d(%04x:%04x).\n",
+		 info->port_index, info->port_type, info->port_subtype);
+	__acpi_early_console_start(info);
+
+	return 0;
+}
+
+static int __init acpi_parse_dbg2(struct acpi_table_header *table)
+{
+	struct acpi_table_dbg2 *dbg2;
+	struct acpi_dbg2_device *entry;
+	void *tbl_end;
+	u32 count = 0;
+	u32 max_entries;
+	struct acpi_debug_port devinfo;
+
+	dbg2 = (struct acpi_table_dbg2 *)table;
+	if (!dbg2) {
+		pr_debug("DBG2 not present.\n");
+		return -ENODEV;
+	}
+
+	tbl_end = (void *)table + table->length;
+
+	entry = (struct acpi_dbg2_device *)((void *)dbg2 + dbg2->info_offset);
+	max_entries = min_t(u32, MAX_ACPI_DBG_PORTS, dbg2->info_count);
+
+	while (((void *)entry) + sizeof(struct acpi_dbg2_device) < tbl_end) {
+		if (entry->revision != 0) {
+			pr_debug("DBG2 revision %d not supported.\n",
+				 entry->revision);
+			return -ENODEV;
+		}
+		if (count < max_entries) {
+			pr_debug("DBG2 PROBE - console %d(%04x:%04x).\n",
+				 count, entry->port_type, entry->port_subtype);
+
+			devinfo.port_index = (u8)count;
+			devinfo.port_type = entry->port_type;
+			devinfo.port_subtype = entry->port_subtype;
+			devinfo.register_count = entry->register_count;
+			devinfo.registers = (struct acpi_generic_address *)
+			    ((void *)entry + entry->base_address_offset);
+			devinfo.namepath_length = entry->namepath_length;
+			devinfo.namepath = (char *)
+			    ((void *)entry + entry->namepath_offset);
+			devinfo.oem_data_length = entry->oem_data_length;
+			devinfo.oem_data = (u8 *)
+			    ((void *)entry + entry->oem_data_offset);
+
+			acpi_early_console_start(&devinfo);
+			count++;
+		}
+
+		entry = (struct acpi_dbg2_device *)
+			((void *)entry + entry->length);
+	}
+
+	return 0;
+}
+
+static int __init acpi_parse_dbgp(struct acpi_table_header *table)
+{
+	struct acpi_table_dbgp *dbgp;
+	struct acpi_debug_port devinfo;
+
+	dbgp = (struct acpi_table_dbgp *)table;
+	if (!dbgp) {
+		pr_debug("DBGP not present.\n");
+		return -ENODEV;
+	}
+
+	pr_debug("DBGP PROBE - console (%04x).\n", dbgp->type);
+
+	devinfo.port_index = 0;
+	devinfo.port_type = ACPI_DBG2_SERIAL_PORT;
+	devinfo.port_subtype = dbgp->type;
+	devinfo.register_count = 1;
+	devinfo.registers = (struct acpi_generic_address *)&dbgp->debug_port;
+	devinfo.namepath_length = 0;
+	devinfo.namepath = NULL;
+	devinfo.oem_data_length = 0;
+	devinfo.oem_data = NULL;
+
+	acpi_early_console_start(&devinfo);
+
+	return 0;
+}
+
+int __init acpi_early_console_probe(void)
+{
+	if (!acpi_early_enabled)
+		return -EINVAL;
+
+	if (acpi_table_parse(ACPI_SIG_DBG2, acpi_parse_dbg2) != 0)
+		acpi_table_parse(ACPI_SIG_DBGP, acpi_parse_dbgp);
+
+	return 0;
+}
+
+int __init acpi_early_console_launch(char *s, int keep)
+{
+	char *e;
+	unsigned long port = 0;
+
+	if (*s)
+		port = simple_strtoul(s, &e, 10);
+
+	return acpi_early_console_enable(port, keep);
+}
+
include/linux/acpi.h +22 -0
index 4f2a762..641366c 100644
@@ -430,4 +430,26 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info);
+int __init acpi_early_console_launch(char *s, int keep);
+int __init acpi_early_console_probe(void);
+/* This interface is arch specific. */
+int __init __acpi_early_console_start(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_probe(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
Signature · 7 lines
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
author
#18 lore raw

RE: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+static __initdata DECLARE_BITMAP(acpi_early_flags,
+MAX_ACPI_DBG_PORTS*2);

It's OK since the keep bit will be derived by the real earlycon drivers in the __acpi_early_console_start() which is an arch specific interface. You can find this usage in the [PATCH v6 2/2].

Quoted 7 lines

drivers/acpi/early_printk.c line 37

Quoted 3 lines
drivers/acpi/early_printk.c new file +3 -0
+	set_bit(port, acpi_early_flags);
+	if (keep)
+		set_bit(port+MAX_ACPI_DBG_PORTS, acpi_early_flags);

Put a comment explaining why you use half of the bitmap to mark them as 'keep'. Thought wouldn't be just easier if you had another bitmap:
acpi_keep_ports?
To set those instead of using this bitmap?

I prefer to put comment here.
I've been a deep embedded engineer for the last 5 years, implementing software containing 4 bus protocol stacks within 128bytes ram and 16kbytes rom, where we used high modularity design patterns. Thus made my habit being critical to ram/rom consumption...

I'm OOO now, the updated version will be sent next week.

Thanks for your comments and best regards/Lv Zheng

#19 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

In reply to Lv Zheng
Quoted 4 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

The license for these specifications only covers BIOS implementations, not OS implementations. Has this had appropriate legal review?

Signature · 1 line
Matthew Garrett | [email protected]
#20 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 9 lines · Matthew Garrett
Quoted 4 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

The license for these specifications only covers BIOS implementations, not OS implementations. Has this had appropriate legal review?

I agree with Matthew. There are potential legal issues with using DBGP/DBGP2 tables in Linux. I had added support for SPCR and DBGP tables many years ago (in early 2.6 kernel timeframe) before Microsoft added this new license. I pulled the code out (in 2.6.14, I think) after Microsoft added the new license to these tables. I agree with Matthew's interpretation that the license is clear only about BIOS vendors being allowed to use these tables. PCDP table in DIG64 spec was introduced to get around the legal issues with using SPCR and DBGP in Linux.

License for DBGP/DBGP2 needs some legal review before this patch can go into Linux.

--
Khalid

#21 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 20 lines · Khalid Aziz
Quoted 9 lines · Matthew Garrett
Quoted 4 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

The license for these specifications only covers BIOS implementations, not OS implementations. Has this had appropriate legal review?

I agree with Matthew. There are potential legal issues with using DBGP/DBGP2 tables in Linux. I had added support for SPCR and DBGP tables many years ago (in early 2.6 kernel timeframe) before Microsoft added this new license. I pulled the code out (in 2.6.14, I think) after Microsoft added the new license to these tables. I agree with Matthew's interpretation that the license is clear only about BIOS vendors being allowed to use these tables. PCDP table in DIG64 spec was introduced to get around the legal issues with using SPCR and DBGP in Linux.

Quoted 2 lines

License for DBGP/DBGP2 needs some legal review before this patch can go into Linux.

Matthew, can you point me at the license Microsoft is using for the DBG2 table? I can download the document from Microsoft's site without seeing any reference to it being licensed only for BIOS implementers. All I see is a "this document is provided 'as-is', blah blah blah" blurb at the beginning of the document. It may be that Microsoft has changed the license on this document in the last 6 months.

I asked some of my contacts at Microsoft about this and was told that the DBG2 spec was supposed to be freed up; but I wasn't able to get anything absolutely confirmed or in writing.

g.

#22 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 6 lines · Grant Likely

Matthew, can you point me at the license Microsoft is using for the DBG2 table? I can download the document from Microsoft's site without seeing any reference to it being licensed only for BIOS implementers. All I see is a "this document is provided 'as-is', blah blah blah" blurb at the beginning of the document. It may be that Microsoft has changed the license on this document in the last 6 months.

The DBGP spec still seems to have the restrictive license, but I can't find it on DBG2.

Signature · 1 line
Matthew Garrett | [email protected]
#23 lore raw

Re: [PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 11 lines · Matthew Garrett
Quoted 6 lines · Grant Likely

Matthew, can you point me at the license Microsoft is using for the DBG2 table? I can download the document from Microsoft's site without seeing any reference to it being licensed only for BIOS implementers. All I see is a "this document is provided 'as-is', blah blah blah" blurb at the beginning of the document. It may be that Microsoft has changed the license on this document in the last 6 months.

The DBGP spec still seems to have the restrictive license, but I can't find it on DBG2.

Thanks Matthew. I'll follow up with Microsoft on DBGP.

g.

author
#24 lore raw

PATCH v6 2/2 ACPI: Add Intel MID SPI early console support.

In reply to Lv Zheng

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

There are two alternatives to use this facility on LPIA platforms:
1. Launch by normal earlycon (on MEDFIELD platforms):
Enable the following kernel configurations:
CONFIG_EARLY_PRINTK_INTEL_MID=y
Pass the following kernel parameter to the kernel:
earlyprintk=mrst
2. Launch by ACPI DBG2 earlycon (on CLOVERVIEW platforms):
Enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Pass the following kernel parameter to the kernel:
earlyprintk=acpi

---
 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   23 +++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Documentation/kernel-parameters.txt +1 -0
index f656765..003ffd9 100644
@@ -762,6 +762,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
+			earlyprintk=mrst
 			earlyprintk=dbgp[debugController#]
 			earlyprintk=acpi[debugController#]
 
arch/x86/Kconfig.debug +23 -0
index 5778082..4a26e2d 100644
@@ -43,9 +43,32 @@ config EARLY_PRINTK
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.  This option does not introduce actual early console into
+	  the kernel binary, but is required by a real early console
+	  implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+	  You should normally N here unless you need to do kernel booting
+	  development.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are always equipped with SPI debug ports and
+	  USB OTG debug ports. To enable these debugging facilities, you
+	  need to pass "earlyprintk=mrst" parameter to the kernel through
+	  boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+	  details.  You should normally N here unless you need to do kernel
+	  booting development.
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
index fc18bf3..8ab0655 100644
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@ extern enum mrst_timer_options mrst_timer_options;
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +11 -1
index bf5b596..9b5ee96 100644
@@ -205,6 +205,16 @@ static inline void early_console_register(struct console *con, int keep_early)
 
 int __init __acpi_early_console_start(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep(info));
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@ static int __init setup_early_printk(char *buf)
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179

214 lines not on this page · raw message

drivers/platform/x86/Makefile +2 -0
index bf7e4f9..6e4ff46 100644
@@ -50,3 +50,5 @@ obj-$(CONFIG_INTEL_MID_POWER_BUTTON)	+= intel_mid_powerbtn.o
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
new file mode 100644
index 0000000..5d9408c
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0

220 lines not on this page · raw message

include/acpi/actbl2.h +1 -0
index 1b2b356..ffa9d62 100644
@@ -341,6 +341,7 @@ struct acpi_dbg2_device {
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
new file mode 100644
index 0000000..edba232
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
Signature · 1 line
1.7.10
author
#25 lore raw

v4 cover ACPI: DBGP/DBG2 early console support for LPIA.

In reply to a message not in the archive

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
Recent Low Power Intel Architecture (LPIA) platforms have utilized this for the SPI UART debug ports that are resident on their debug boards.

This patch set enables the DBGP/DBG2 debug ports as an Linux early console launcher.
The SPI UART debug ports support is also refined to co-exist with this new usage model.

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.

There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 3 of this patch set is the first version that will be published in the Linux community. Earlier versions are reviewed internally in Intel. This patch set keeps the version number to track the history that is known to Intel internal developers.
Version 4 of this patch set fixed bunch of CodingStyle issues.

Lv Zheng (2):
ACPI: Add early console framework for DBGP/DBG2.
ACPI: Add Intel MID SPI early console support.

 Documentation/kernel-parameters.txt        |    2 +
 arch/x86/Kconfig.debug                     |   38 +++++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/acpi/boot.c                |    1 +
 arch/x86/kernel/early_printk.c             |   25 +++-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/acpi/Makefile                      |    2 +
 drivers/acpi/early_printk.c                |  201 +++++++++++++++++++++++++
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/acpi.h                       |   24 +++
 include/linux/intel_mid_early.h            |   12 ++
 14 files changed, 540 insertions(+), 181 deletions(-)
 create mode 100644 drivers/acpi/early_printk.c
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Signature · 1 line
1.7.10
author
#26 lore raw

v4 cover ACPI: DBGP/DBG2 early console support for LPIA.

In reply to a message not in the archive

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
Recent Low Power Intel Architecture (LPIA) platforms have utilized this for the SPI UART debug ports that are resident on their debug boards.

This patch set enables the DBGP/DBG2 debug ports as an Linux early console launcher.
The SPI UART debug ports support is also refined to co-exist with this new usage model.

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.

There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 3 of this patch set is the first version that will be published in the Linux community. Earlier versions are reviewed internally in Intel. This patch set keeps the version number to track the history that is known to Intel internal developers.
Version 4 of this patch set fixed bunch of CodingStyle issues.

Lv Zheng (2):
ACPI: Add early console framework for DBGP/DBG2.
ACPI: Add Intel MID SPI early console support.

 Documentation/kernel-parameters.txt        |    2 +
 arch/x86/Kconfig.debug                     |   38 +++++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/acpi/boot.c                |    1 +
 arch/x86/kernel/early_printk.c             |   25 +++-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/acpi/Makefile                      |    2 +
 drivers/acpi/early_printk.c                |  201 +++++++++++++++++++++++++
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/acpi.h                       |   24 +++
 include/linux/intel_mid_early.h            |   12 ++
 14 files changed, 540 insertions(+), 181 deletions(-)
 create mode 100644 drivers/acpi/early_printk.c
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Signature · 1 line
1.7.10
author
#27 lore raw

PATCH v5 1/2 ACPI: Add early console framework for DBGP/DBG2.

In reply to a message not in the archive

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

This patch enables the DBGP/DBG2 debug ports as Linux early console launcher. Individual early console drivers are also needed to get the early kernel messages dumped on the consoles. For example, to use the SPI UART early console for the Low Power Intel Architecture (LPIA) platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.
There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 1:
1. Enables single DBG2 debug port support.
Version 2:
1. Applies Rui's comments.
Version 3:
1. Applies Len's comments (earlycon should be disabled by default).
2. Enables single DBG2 debug ports support.
Version 4:
1. Fixes the CodingStyle issues reported by checkpatch.pl.
2. Enables single DBGP debug port support.
Version 5:
1. Enables multiple DBG2 debug ports support.
2. Applies Konrad's comments (pr_debug should be used in earlycon).
3. Changes kstrtoul back to simple_strtoul.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in the x86 specific booting codes. The kstrtoul will return error on strings like "acpi0,keep". This will leave one CodingStyle issue reported by the checkpatch.pl.

---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  173 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   22 +++++
 7 files changed, 227 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
index ad7e2e5..f656765 100644
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
index b322f12..5778082 100644
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
index b2297e5..cc10ea5 100644
@@ -1518,6 +1518,7 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 
+	acpi_early_console_probe();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
index 9b9f18b..bf5b596 100644
@@ -200,6 +200,15 @@ static inline void early_console_register(struct console *con, int keep_early)
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init __acpi_early_console_start(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@ static int __init setup_early_printk(char *buf)
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_launch(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
index 47199e2..99dbd64 100644
@@ -46,6 +46,8 @@ ifdef CONFIG_ACPI_VIDEO
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +173 -0

173 lines not on this page · raw message

include/linux/acpi.h +22 -0
index 4f2a762..641366c 100644
@@ -430,4 +430,26 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info);
+int __init acpi_early_console_launch(char *s, int keep);
+int __init acpi_early_console_probe(void);
+/* This interface is arch specific. */
+int __init __acpi_early_console_start(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_probe(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
Signature · 1 line
1.7.10
#28 lore raw

Re: [PATCH v5 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 137 lines · Lv Zheng

Microsoft Debug Port Table (DBGP or DBG2) is used by the Windows SoC platforms to describe their debugging facilities.
DBGP: http://msdn.microsoft.com/en-us/windows/hardware/hh134821
DBG2: http://msdn.microsoft.com/en-us/library/windows/hardware/hh673515

This patch enables the DBGP/DBG2 debug ports as Linux early console launcher. Individual early console drivers are also needed to get the early kernel messages dumped on the consoles. For example, to use the SPI UART early console for the Low Power Intel Architecture (LPIA) platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in your the boot loader configuration file:
earlyprintk=acpi

There is a dilemma in designing this patch set. Let me describe it in details.
There should be three steps to enable an early console for an operating system:
1. Probe: In this stage, the Linux kernel can detect the early consoles and the base address of their register block can be determined. This can be done by parsing the descriptors in the ACPI DBGP/DBG2 tables. Note that acpi_table_init() must be called before parsing.
2. Setup: In this stage, the Linux kernel can apply user specified configuration options (ex. baudrate of serial ports) for the early consoles. This is done by parsing the early parameters passed to the kernel from the boot loaders. Note that parse_early_params() is called very early to allow parameters to be passed to other kernel subsystems.
3. Start: In this stage, the Linux kernel can make the consoles ready to output logs. Since the early consoles are always used for the kernel boot up debugging, this must be done as early as possible to arm the kernel with the highest testability for other kernel subsystems. Note that, this stage happens when the register_console() is called.
The preferred sequence for the above steps is:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

But unfortunately, in the current x86 implementation, early parameters and early printk initialization are called before acpi_table_init() which depends on the early memory mapping facility.
There are some choices for me to design this patch set:
1. Invoking acpi_table_init() before parse_early_param() to maintain the sequence:

   +-----------------+    +-------------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-----------------+    +-------------------+    +--------------------+

This requires other subsystem maintainers' review to ensure no regressions will be introduced. At the first glance, I found there might be problems for the EFI subsystsm:
The EFI boot services and runtime services are mixed up in the x86 specific initialization process before the ACPI table initialization. Things are much worse that you even cannot disable the runtime services while still allow the boot services codes to be executed in the kernel compilation stage. Enabling the early consoles after the ACPI table initialization will make it difficult to debug the runtime BIOS bugs. If any progress is made to the kernel boot sequences, please let me know. I'll be willing to redesign the ACPI DBGP/DBG2 console probing facility. You can reach me at <[email protected]> and <[email protected]>.
2. Modifying the above sequece to make it look like:

   +-------------------+    +-----------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-------------------+    +-----------------+    +--------------------+

Early consoles started in this style will lose part of the testability in the kernel boot up sequence. If the system does not crash very early, developers still can see the bufferred kernel outputs when the register_console() is called.
Current early console implementations need to be modified to be compatible with this design. The original codes need to be split up into tow parts:
1. Detecting hardware. This part can be called in the PROBE stage.
2. Applying user parameters. This part can be called in the SETUP stage.
Individual early console drver maintainers need to be involved to avoid regressions that might occur if we do things in this way. And the maintainers can offer better tests than I can do.
3. Introducing a brand new debugging facility that does not relate to the current early console implementation to allow the early consoles to be automatically detected.

   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +--------------------+
   +-----------------+    +--------------------+
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-----------------+    +--------------------+
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +-------------------+    +--------------------+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +-------------------+    +....................+
                            | ACPI DBGP LAUNCH   | ->
                            +--------------------+
      +-----------------+    +--------------------+
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
      +-----------------+    +--------------------+

Version 1:
1. Enables single DBG2 debug port support.
Version 2:
1. Applies Rui's comments.
Version 3:
1. Applies Len's comments (earlycon should be disabled by default).
2. Enables single DBG2 debug ports support.
Version 4:
1. Fixes the CodingStyle issues reported by checkpatch.pl.
2. Enables single DBGP debug port support.
Version 5:
1. Enables multiple DBG2 debug ports support.
2. Applies Konrad's comments (pr_debug should be used in earlycon).
3. Changes kstrtoul back to simple_strtoul.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in the x86 specific booting codes. The kstrtoul will return error on strings like "acpi0,keep". This will leave one CodingStyle issue reported by the checkpatch.pl.

Quoted 5 lines

Please don't include that unless I (or other folks looking at your code) say explicitly 'Acked' or 'Reviewed-by'

Quoted 114 lines
---
 Documentation/kernel-parameters.txt |    1 +
 arch/x86/Kconfig.debug              |   15 +++
 arch/x86/kernel/acpi/boot.c         |    1 +
 arch/x86/kernel/early_printk.c      |   13 +++
 drivers/acpi/Makefile               |    2 +
 drivers/acpi/early_printk.c         |  173 +++++++++++++++++++++++++++++++++++
 include/linux/acpi.h                |   22 +++++
 7 files changed, 227 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c
Documentation/kernel-parameters.txt +1 -0
index ad7e2e5..f656765 100644
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=acpi[debugController#]
 
 			Append ",keep" to not disable it when the real console
 			takes over.
arch/x86/Kconfig.debug +15 -0
index b322f12..5778082 100644
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+	bool "Early printk launcher via ACPI debug port tables"
+	depends on EARLY_PRINTK && ACPI
+	---help---
+	  Write kernel log output directly into the debug ports described
+	  in the ACPI tables known as DBGP and DBG2.
+
+	  To enable such debugging facilities, you need to enable this
+	  configuration option and append the "earlyprintk=acpi" kernel
+	  parameter through the boot loaders.  Please refer the
+	  "Documentation/kernel-parameters.txt" for details.  Since this
+	  is an early console launcher, you still need to enable actual
+	  early console drivers that are suitable for your platform.
+	  If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/x86/kernel/acpi/boot.c +1 -0
index b2297e5..cc10ea5 100644
@@ -1518,6 +1518,7 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 
+	acpi_early_console_probe();
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
 	/*
arch/x86/kernel/early_printk.c +13 -0
index 9b9f18b..bf5b596 100644
@@ -200,6 +200,15 @@ static inline void early_console_register(struct console *con, int keep_early)
 	register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include <linux/acpi.h>
+
+int __init __acpi_early_console_start(struct acpi_debug_port *info)
+{
+	return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
 	int keep;
@@ -236,6 +245,10 @@ static int __init setup_early_printk(char *buf)
 		if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
 			early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+		if (!strncmp(buf, "acpi", 4))
+			acpi_early_console_launch(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
 		if (!strncmp(buf, "xen", 3))
 			early_console_register(&xenboot_console, keep);
drivers/acpi/Makefile +2 -0
index 47199e2..99dbd64 100644
@@ -46,6 +46,8 @@ ifdef CONFIG_ACPI_VIDEO
 acpi-y				+= video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)	+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
drivers/acpi/early_printk.c new file +3 -0
new file mode 100644
index 0000000..3e5c1f3
@@ -0,0 +1,173 @@
+/*
+ * acpi/early_printk.c - ACPI Boot-Time Debug Ports
+ *

drivers/acpi/early_printk.c line 13

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+ * Copyright (c) 2012, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * 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; version 2
+ * of the License.
+ */
+
+#define DEBUG

That should not be the default case.

drivers/acpi/early_printk.c line 26

Quoted 13 lines
drivers/acpi/early_printk.c new file +13 -0
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/bitmap.h>
+#include <linux/bootmem.h>
+
+#define MAX_ACPI_DBG_PORTS	16
+
+DECLARE_BITMAP(acpi_early_flags, MAX_ACPI_DBG_PORTS);

static?

drivers/acpi/early_printk.c line 27

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+int acpi_early_enabled;

__read_mostly and you could also make it a bool.

drivers/acpi/early_printk.c line 36

Quoted 9 lines
drivers/acpi/early_printk.c new file +9 -0
+
+static int acpi_early_console_enable(u8 port, int keep)
+{
+	if (port >= MAX_ACPI_DBG_PORTS)
+		return -ENODEV;
+
+	set_bit(port, acpi_early_flags);
+	if (keep)
+		set_bit(port+MAX_ACPI_DBG_PORTS, acpi_early_flags);

Huh? The bitmap is up to MAX_ACPI_DB_PORTS, but here you offset it past that? Why?

Quoted 4 lines
drivers/acpi/early_printk.c new file +4 -0
+	acpi_early_enabled = 1;
+
+	pr_debug("early: DBGx LAUNCH - console %d.\n", port);
+

drivers/acpi/early_printk.c line 50

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+	return 0;
+}
+
+static inline bool acpi_early_console_enabled(u8 port)
+{
+	BUG_ON(port >= MAX_ACPI_DBG_PORTS);
+	return test_bit(port, acpi_early_flags);
+}
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info)

Why not make it 'bool' like the other (acpi_early_console_enabled)?

drivers/acpi/early_printk.c line 59

Quoted 9 lines
drivers/acpi/early_printk.c new file +9 -0
+{
+	BUG_ON(!info || info->port_index >= MAX_ACPI_DBG_PORTS);
+	return test_bit(info->port_index+MAX_ACPI_DBG_PORTS, acpi_early_flags);
+}
+
+static int __init acpi_early_console_start(struct acpi_debug_port *info)
+{
+	if (!acpi_early_console_enabled(info->port_index))
+		return 0;

Not -ENODEV?

Quoted 21 lines
drivers/acpi/early_printk.c new file +21 -0
+
+	pr_debug("early: DBGx START - console %d(%04x:%04x).\n",
+		 info->port_index, info->port_type, info->port_subtype);
+	__acpi_early_console_start(info);
+
+	return 0;
+}
+
+static int __init acpi_parse_dbg2(struct acpi_table_header *table)
+{
+	struct acpi_table_dbg2 *dbg2;
+	struct acpi_dbg2_device *entry;
+	unsigned int count = 0;
+	unsigned long tbl_end;
+	unsigned int max_entries;
+	struct acpi_debug_port devinfo;
+
+	dbg2 = (struct acpi_table_dbg2 *)table;
+	if (!dbg2) {
+		pr_debug("early: DBG2 not present.\n");
+		return -ENODEV;

drivers/acpi/early_printk.c line 90

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+	}
+
+	tbl_end = (unsigned long)table + table->length;
+
+	entry = (struct acpi_dbg2_device *)
+		((unsigned long)dbg2 + dbg2->info_offset);
+	max_entries = min_t(u32, MAX_ACPI_DBG_PORTS, dbg2->info_count);
+
+	while (((unsigned long)entry) + sizeof(struct acpi_dbg2_device) <
+	       tbl_end) {

Just make it one line. Ignore the 80 characters limit here.

drivers/acpi/early_printk.c line 96

Quoted 6 lines
drivers/acpi/early_printk.c new file +6 -0
+		if (entry->revision != 0) {
+			pr_debug("early: DBG2 revision %d not supported.\n",
+				 entry->revision);
+			return -ENODEV;
+		}
+		if (!max_entries || count++ < max_entries) {

How about you just make this 'count'

drivers/acpi/early_printk.c line 101

Quoted 5 lines
drivers/acpi/early_printk.c new file +5 -0
+			pr_debug("early: DBG2 PROBE - console %d(%04x:%04x).\n",
+				 count-1,
+				 entry->port_type, entry->port_subtype);
+
+			devinfo.port_index = (u8)count-1;

Then you don't this 'count -1'

drivers/acpi/early_printk.c line 114

Quoted 13 lines
drivers/acpi/early_printk.c new file +13 -0
+			devinfo.port_type = entry->port_type;
+			devinfo.port_subtype = entry->port_subtype;
+			devinfo.register_count = entry->register_count;
+			devinfo.registers = (struct acpi_generic_address *)
+			    ((unsigned long)entry + entry->base_address_offset);
+			devinfo.namepath_length = entry->namepath_length;
+			devinfo.namepath = (char *)
+			    ((unsigned long)entry + entry->namepath_offset);
+			devinfo.oem_data_length = entry->oem_data_length;
+			devinfo.oem_data = (u8 *)
+			    ((unsigned long)entry + entry->oem_data_offset);
+
+			acpi_early_console_start(&devinfo);

no check of the return value to see whether you should return immediately?

drivers/acpi/early_printk.c line 115

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+		}

and then do
count++ here?

Quoted 22 lines
drivers/acpi/early_printk.c new file +22 -0
+
+		entry = (struct acpi_dbg2_device *)
+		    ((unsigned long)entry + entry->length);
+	}
+
+	return 0;
+}
+
+static int __init acpi_parse_dbgp(struct acpi_table_header *table)
+{
+	struct acpi_table_dbgp *dbgp;
+	struct acpi_debug_port devinfo;
+
+	dbgp = (struct acpi_table_dbgp *)table;
+	if (!dbgp) {
+		pr_debug("early: DBGP not present.\n");
+		return -ENODEV;
+	}
+
+	pr_debug("early: DBGP PROBE - console (%04x).\n", dbgp->type);
+
+	devinfo.port_index = 0;

drivers/acpi/early_printk.c line 147

Quoted 10 lines
drivers/acpi/early_printk.c new file +10 -0
+	devinfo.port_type = ACPI_DBG2_SERIAL_PORT;
+	devinfo.port_subtype = dbgp->type;
+	devinfo.register_count = 1;
+	devinfo.registers = (struct acpi_generic_address *)&dbgp->debug_port;
+	devinfo.namepath_length = 0;
+	devinfo.namepath = NULL;
+	devinfo.oem_data_length = 0;
+	devinfo.oem_data = NULL;
+
+	acpi_early_console_start(&devinfo);

how about 'return acpi_early_console_start(..)'

Quoted 65 lines
drivers/acpi/early_printk.c new file +26 -0
+
+	return 0;
+}
+
+int __init acpi_early_console_probe(void)
+{
+	if (!acpi_early_enabled)
+		return -EINVAL;
+
+	if (acpi_table_parse(ACPI_SIG_DBG2, acpi_parse_dbg2) != 0)
+		acpi_table_parse(ACPI_SIG_DBGP, acpi_parse_dbgp);
+
+	return 0;
+}
+
+int __init acpi_early_console_launch(char *s, int keep)
+{
+	char *e;
+	unsigned long port = 0;
+
+	if (*s)
+		port = simple_strtoul(s, &e, 10);
+
+	return acpi_early_console_enable(port, keep);
+}
+
include/linux/acpi.h +22 -0
index 4f2a762..641366c 100644
@@ -430,4 +430,26 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+struct acpi_debug_port {
+	u8 port_index;
+	u16 port_type;
+	u16 port_subtype;
+	u16 register_count;
+	struct acpi_generic_address *registers;
+	u16 namepath_length;
+	char *namepath;
+	u16 oem_data_length;
+	u8 *oem_data;
+};
+
+int __init acpi_early_console_keep(struct acpi_debug_port *info);
+int __init acpi_early_console_launch(char *s, int keep);
+int __init acpi_early_console_probe(void);
+/* This interface is arch specific. */
+int __init __acpi_early_console_start(struct acpi_debug_port *info);
+#else
+static int acpi_early_console_probe(void) { return 0; }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
Signature · 6 lines
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author NAK
#29 lore raw

RE: [PATCH v5 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 7 lines
Quoted 5 lines

Please don't include that unless I (or other folks looking at your code) say explicitly 'Acked' or 'Reviewed-by'

ACK.
I'll remove these names and resend. Thanks.

Quoted 2 lines
Quoted 1 line

+#define DEBUG

That should not be the default case.

RFC.
If we do not add ignore_loglevel to the command line, the acpi earlycon will be mute just as what you want.
Do you really want this to be:
#undef DEBUG
If we do this, all pr_debug invocations in this file will be empty in compilation stage and are there any other means for us to view the output of ACPI earlycon without recompiling?

Quoted 2 lines
Quoted 1 line

+DECLARE_BITMAP(acpi_early_flags, MAX_ACPI_DBG_PORTS);

static?

ACK.
I'll do the modification.

Quoted 2 lines
Quoted 1 line

+int acpi_early_enabled;

__read_mostly and you could also make it a bool.

NAK.
I think this variable will be read only once and written up to 16 times so __read_mostly is not required. I'll check and add __init and __initdata for this patch.

Quoted 5 lines

drivers/acpi/early_printk.c line 36

Quoted 3 lines
drivers/acpi/early_printk.c new file +3 -0
+	set_bit(port, acpi_early_flags);
+	if (keep)
+		set_bit(port+MAX_ACPI_DBG_PORTS, acpi_early_flags);

Huh? The bitmap is up to MAX_ACPI_DB_PORTS, but here you offset it past that? Why?

ACK.
It's my mistake. The size of the bitmap should be "MAX_ACPI_DBG_PORTS<<1 or MAX_ACPI_DBG_PORTS*2". The reason is:
I think MAX_ACPI_DBG_PORTS=4 is enough in this case.
Since the systems running Linux are 32/64 bit architectures, using 2 bitmaps will be waste. As the systems are at least 32 bit, the MAX_ACPI_DB_PORTS is defined as 16 to make full use of the bitmap.

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if (!acpi_early_console_enabled(info->port_index))
+		return 0;

Not -ENODEV?

NAK.
This is to support "MULTIPLE DBG2 debug ports".

** MULTIPLE DBGP table versions and MULTIPLE DBG2 debug ports support **
The whole patch takes ENODEV as the semantics of "table not exist or table version not supported" in PROBE/START stage so that we can obtain the ability of probing Microsoft's future tables in the order from DBGn, ..., DBG2, DBGP. We should not return here as users may pass the following command line:
earlyprintk=acpi2,keep
to let the first 2 debug ports mute, but take the 3rd as a Linux earlycon.

Quoted 3 lines

drivers/acpi/early_printk.c line 90

Quoted 2 lines
drivers/acpi/early_printk.c new file +2 -0
+	while (((unsigned long)entry) + sizeof(struct acpi_dbg2_device) <
+	       tbl_end) {

Just make it one line. Ignore the 80 characters limit here.

ACK.
I'll try to implement this within 80 characters.

Quoted 9 lines

drivers/acpi/early_printk.c line 96

Quoted 1 line
drivers/acpi/early_printk.c new file +1 -0
+		if (!max_entries || count++ < max_entries) {

How about you just make this 'count'

drivers/acpi/early_printk.c line 101

Quoted 4 lines
drivers/acpi/early_printk.c new file +4 -0
+			pr_debug("early: DBG2 PROBE - console %d(%04x:%04x).\n",
+				 count-1,
+				 entry->port_type, entry->port_subtype);
+			devinfo.port_index = (u8)count-1;

Then you don't this 'count -1'
and then do
count++ here?

ACK.
It's my mistake, the previous version uses port_index=1 as the first debug port, but this version takes 0 as the first port.

Quoted 2 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+			acpi_early_console_start(&devinfo);

no check of the return value to see whether you should return immediately?

NAK.
See " MULTIPLE DBGP tables and MULTIPLE DBG2 debug ports support" above.

Quoted 2 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	acpi_early_console_start(&devinfo);

how about 'return acpi_early_console_start(..)'

NAK.
See " MULTIPLE DBGP tables and MULTIPLE DBG2 debug ports support" above.

Quoted 2 lines

drivers/acpi/early_printk.c line 158

Quoted 2 lines
drivers/acpi/early_printk.c new file +2 -0
+	if (acpi_table_parse(ACPI_SIG_DBG2, acpi_parse_dbg2) != 0)
+		acpi_table_parse(ACPI_SIG_DBGP, acpi_parse_dbgp);

RFC.
This is to support "MULTIPLE DBGP table versions".

#30 lore raw

Re: [PATCH v5 1/2] ACPI: Add early console framework for DBGP/DBG2.

Quoted 8 lines · Lv
Quoted 7 lines
Quoted 5 lines

Please don't include that unless I (or other folks looking at your code) say explicitly 'Acked' or 'Reviewed-by'

Quoted 7 lines

ACK.
I'll remove these names and resend. Thanks.

Quoted 2 lines
Quoted 1 line

+#define DEBUG

That should not be the default case.

RFC.

The title of the patch does not have RFC anymore.. Please put it back then.

Quoted 4 lines

If we do not add ignore_loglevel to the command line, the acpi earlycon will be mute just as what you want.
Do you really want this to be:
#undef DEBUG
If we do this, all pr_debug invocations in this file will be empty in compilation stage and are there any other means for us to view the output of ACPI earlycon without recompiling?

Correct. By the time you remove the 'RFC' part this should be the default.

Quoted 32 lines
Quoted 3 lines
Quoted 2 lines

+DECLARE_BITMAP(acpi_early_flags, MAX_ACPI_DBG_PORTS);

static?

ACK.
I'll do the modification.

Quoted 2 lines
Quoted 1 line

+int acpi_early_enabled;

__read_mostly and you could also make it a bool.

NAK.
I think this variable will be read only once and written up to 16 times so __read_mostly is not required. I'll check and add __init and __initdata for this patch.

Quoted 5 lines

drivers/acpi/early_printk.c line 36

Quoted 3 lines
drivers/acpi/early_printk.c new file +3 -0
+	set_bit(port, acpi_early_flags);
+	if (keep)
+		set_bit(port+MAX_ACPI_DBG_PORTS, acpi_early_flags);

Huh? The bitmap is up to MAX_ACPI_DB_PORTS, but here you offset it past that? Why?

ACK.
It's my mistake. The size of the bitmap should be "MAX_ACPI_DBG_PORTS<<1 or MAX_ACPI_DBG_PORTS*2". The reason is:
I think MAX_ACPI_DBG_PORTS=4 is enough in this case.
Since the systems running Linux are 32/64 bit architectures, using 2 bitmaps will be waste. As the systems are at least 32 bit, the MAX_ACPI_DB_PORTS is defined as 16 to make full use of the bitmap.

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if (!acpi_early_console_enabled(info->port_index))
+		return 0;

Not -ENODEV?

Quoted 8 lines

NAK.
This is to support "MULTIPLE DBG2 debug ports".

** MULTIPLE DBGP table versions and MULTIPLE DBG2 debug ports support **
The whole patch takes ENODEV as the semantics of "table not exist or table version not supported" in PROBE/START stage so that we can obtain the ability of probing Microsoft's future tables in the order from DBGn, ..., DBG2, DBGP. We should not return here as users may pass the following command line:
earlyprintk=acpi2,keep
to let the first 2 debug ports mute, but take the 3rd as a Linux earlycon.

OK? How will this function get called three times then? I thought it would just get called once?

Quoted 7 lines
Quoted 4 lines

drivers/acpi/early_printk.c line 90

Quoted 3 lines
drivers/acpi/early_printk.c new file +2 -0
+	while (((unsigned long)entry) + sizeof(struct acpi_dbg2_device) <
+	       tbl_end) {

Just make it one line. Ignore the 80 characters limit here.

ACK.
I'll try to implement this within 80 characters.

Well, you don't have to - not for this.

Quoted 33 lines
Quoted 10 lines

drivers/acpi/early_printk.c line 96

Quoted 2 lines
drivers/acpi/early_printk.c new file +1 -0
+		if (!max_entries || count++ < max_entries) {

How about you just make this 'count'

drivers/acpi/early_printk.c line 101

Quoted 4 lines
drivers/acpi/early_printk.c new file +4 -0
+			pr_debug("early: DBG2 PROBE - console %d(%04x:%04x).\n",
+				 count-1,
+				 entry->port_type, entry->port_subtype);
+			devinfo.port_index = (u8)count-1;

Then you don't this 'count -1'
and then do
count++ here?

ACK.
It's my mistake, the previous version uses port_index=1 as the first debug port, but this version takes 0 as the first port.

Quoted 2 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+			acpi_early_console_start(&devinfo);

no check of the return value to see whether you should return immediately?

NAK.
See " MULTIPLE DBGP tables and MULTIPLE DBG2 debug ports support" above.

Quoted 2 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	acpi_early_console_start(&devinfo);

how about 'return acpi_early_console_start(..)'

NAK.
See " MULTIPLE DBGP tables and MULTIPLE DBG2 debug ports support" above.

Quoted 2 lines

drivers/acpi/early_printk.c line 158

Quoted 2 lines
drivers/acpi/early_printk.c new file +2 -0
+	if (acpi_table_parse(ACPI_SIG_DBG2, acpi_parse_dbg2) != 0)
+		acpi_table_parse(ACPI_SIG_DBGP, acpi_parse_dbgp);

RFC.
This is to support "MULTIPLE DBGP table versions".

author NAK
#31 lore raw

RE: [PATCH v5 1/2] ACPI: Add early console framework for DBGP/DBG2.

In reply to Konrad Rzeszutek Wilk
Quoted 3 lines
Quoted 1 line

+int __init acpi_early_console_keep(struct acpi_debug_port *info)

Why not make it 'bool' like the other (acpi_early_console_enabled)?

NAK.
"keep" is "int" in "setup_early_printk".

Best regards/Lv Zheng

author
#32 lore raw

PATCH v5 2/2 ACPI: Add Intel MID SPI early console support.

In reply to a message not in the archive

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in the boot loader configuration file:
earlyprintk=acpi

---
 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   23 +++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Documentation/kernel-parameters.txt +1 -0
index f656765..003ffd9 100644
@@ -762,6 +762,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
+			earlyprintk=mrst
 			earlyprintk=dbgp[debugController#]
 			earlyprintk=acpi[debugController#]
 
arch/x86/Kconfig.debug +23 -0
index 5778082..4a26e2d 100644
@@ -43,9 +43,32 @@ config EARLY_PRINTK
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.  This option does not introduce actual early console into
+	  the kernel binary, but is required by a real early console
+	  implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+	  You should normally N here unless you need to do kernel booting
+	  development.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are always equipped with SPI debug ports and
+	  USB OTG debug ports. To enable these debugging facilities, you
+	  need to pass "earlyprintk=mrst" parameter to the kernel through
+	  boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+	  details.  You should normally N here unless you need to do kernel
+	  booting development.
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
index fc18bf3..8ab0655 100644
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@ extern enum mrst_timer_options mrst_timer_options;
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +11 -1
index bf5b596..9b5ee96 100644
@@ -205,6 +205,16 @@ static inline void early_console_register(struct console *con, int keep_early)
 
 int __init __acpi_early_console_start(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep(info));
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@ static int __init setup_early_printk(char *buf)
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179

214 lines not on this page · raw message

drivers/platform/x86/Makefile +2 -0
index bf7e4f9..6e4ff46 100644
@@ -50,3 +50,5 @@ obj-$(CONFIG_INTEL_MID_POWER_BUTTON)	+= intel_mid_powerbtn.o
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
new file mode 100644
index 0000000..5d9408c
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0

220 lines not on this page · raw message

include/acpi/actbl2.h +1 -0
index 1b2b356..ffa9d62 100644
@@ -341,6 +341,7 @@ struct acpi_dbg2_device {
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
new file mode 100644
index 0000000..edba232
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
Signature · 1 line
1.7.10
#33 lore raw

Re: [PATCH v5 2/2] ACPI: Add Intel MID SPI early console support.

Quoted 6 lines · Lv Zheng

DesignWare SPI UART is used as one of the debug ports on Low Power Intel Architecture (LPIA) platforms. This patch is introduced to support this debugging console reported by ACPI DBGP/DBG2. The original MID SPI early console stuff is also refined to co-exist with the new ACPI usage model.

Quoted 7 lines

To use this facility on LPIA platforms, you need to enable the following kernel configurations:
CONFIG_EARLY_PRINTK_ACPI=y CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel command line in the boot loader configuration file:
earlyprintk=acpi

.. or earlyprintk=mrst
?

Quoted 93 lines
---
 Documentation/kernel-parameters.txt        |    1 +
 arch/x86/Kconfig.debug                     |   23 +++
 arch/x86/include/asm/mrst.h                |    2 +-
 arch/x86/kernel/early_printk.c             |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +----------------------
 drivers/platform/x86/Makefile              |    2 +
 drivers/platform/x86/early/Makefile        |    5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 ++++++++++++++++++++++++++++
 include/acpi/actbl2.h                      |    1 +
 include/linux/intel_mid_early.h            |   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h
Documentation/kernel-parameters.txt +1 -0
index f656765..003ffd9 100644
@@ -762,6 +762,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
+			earlyprintk=mrst
 			earlyprintk=dbgp[debugController#]
 			earlyprintk=acpi[debugController#]
 
arch/x86/Kconfig.debug +23 -0
index 5778082..4a26e2d 100644
@@ -43,9 +43,32 @@ config EARLY_PRINTK
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+	bool "Early printk for Intel MID SPI UART port"
+	depends on EARLY_PRINTK
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are using DesignWare SPI UART as its debug
+	  console.  This option does not introduce actual early console into
+	  the kernel binary, but is required by a real early console
+	  implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+	  You should normally N here unless you need to do kernel booting
+	  development.
+
 config EARLY_PRINTK_INTEL_MID
 	bool "Early printk for Intel MID platform support"
 	depends on EARLY_PRINTK && X86_INTEL_MID
+	select EARLY_PRINTK_INTEL_MID_SPI
+	---help---
+	  Write kernel log output directly into the MID SPI UART debug port.
+
+	  Intel MID platforms are always equipped with SPI debug ports and
+	  USB OTG debug ports. To enable these debugging facilities, you
+	  need to pass "earlyprintk=mrst" parameter to the kernel through
+	  boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+	  details.  You should normally N here unless you need to do kernel
+	  booting development.
 
 config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
arch/x86/include/asm/mrst.h +1 -1
index fc18bf3..8ab0655 100644
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include <linux/sfi.h>
+#include <linux/intel_mid_early.h>
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@ extern enum mrst_timer_options mrst_timer_options;
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX	8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
arch/x86/kernel/early_printk.c +0 -0
index bf5b596..9b5ee96 100644

arch/x86/kernel/early_printk.c static inline void early_console_register(struct console *con, int keep_early) · line 211

Quoted 7 lines
arch/x86/kernel/early_printk.c +4 -0
@@ -205,6 +205,16 @@ static inline void early_console_register(struct console *con, int keep_early)
 
 int __init __acpi_early_console_start(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {

Is it ever going to be zero?

Quoted 525 lines
arch/x86/kernel/early_printk.c +7 -1
+		mid_spi_early_console_init((u32)(info->registers[0].address));
+		early_console_register(&mid_spi_early_console,
+				       acpi_early_console_keep(info));
+	}
+#endif
+
 	return 0;
 }
 #endif
@@ -256,7 +266,7 @@ static int __init setup_early_printk(char *buf)
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
 		if (!strncmp(buf, "mrst", 4)) {
 			mrst_early_console_init();
-			early_console_register(&early_mrst_console, keep);
+			early_console_register(&mid_spi_early_console, keep);
 		}
 
 		if (!strncmp(buf, "hsu", 3)) {
arch/x86/platform/mrst/early_printk_mrst.c +7 -179
index 028454f..7afbf18 100644
@@ -29,82 +29,8 @@
 #include <asm/pgtable.h>
 #include <asm/mrst.h>
 
-#define MRST_SPI_TIMEOUT		0x200000
 #define MRST_REGBASE_SPI0		0xff128000
 #define MRST_REGBASE_SPI1		0xff128400
-#define MRST_CLK_SPI0_REG		0xff11d86c
-
-/* Bit fields in CTRLR0 */
-#define SPI_DFS_OFFSET			0
-
-#define SPI_FRF_OFFSET			4
-#define SPI_FRF_SPI			0x0
-#define SPI_FRF_SSP			0x1
-#define SPI_FRF_MICROWIRE		0x2
-#define SPI_FRF_RESV			0x3
-
-#define SPI_MODE_OFFSET			6
-#define SPI_SCPH_OFFSET			6
-#define SPI_SCOL_OFFSET			7
-#define SPI_TMOD_OFFSET			8
-#define	SPI_TMOD_TR			0x0		/* xmit & recv */
-#define SPI_TMOD_TO			0x1		/* xmit only */
-#define SPI_TMOD_RO			0x2		/* recv only */
-#define SPI_TMOD_EPROMREAD		0x3		/* eeprom read mode */
-
-#define SPI_SLVOE_OFFSET		10
-#define SPI_SRL_OFFSET			11
-#define SPI_CFS_OFFSET			12
-
-/* Bit fields in SR, 7 bits */
-#define SR_MASK				0x7f		/* cover 7 bits */
-#define SR_BUSY				(1 << 0)
-#define SR_TF_NOT_FULL			(1 << 1)
-#define SR_TF_EMPT			(1 << 2)
-#define SR_RF_NOT_EMPT			(1 << 3)
-#define SR_RF_FULL			(1 << 4)
-#define SR_TX_ERR			(1 << 5)
-#define SR_DCOL				(1 << 6)
-
-struct dw_spi_reg {
-	u32	ctrl0;
-	u32	ctrl1;
-	u32	ssienr;
-	u32	mwcr;
-	u32	ser;
-	u32	baudr;
-	u32	txfltr;
-	u32	rxfltr;
-	u32	txflr;
-	u32	rxflr;
-	u32	sr;
-	u32	imr;
-	u32	isr;
-	u32	risr;
-	u32	txoicr;
-	u32	rxoicr;
-	u32	rxuicr;
-	u32	msticr;
-	u32	icr;
-	u32	dmacr;
-	u32	dmatdlr;
-	u32	dmardlr;
-	u32	idr;
-	u32	version;
-
-	/* Currently operates as 32 bits, though only the low 16 bits matter */
-	u32	dr;
-} __packed;
-
-#define dw_readl(dw, name)		__raw_readl(&(dw)->name)
-#define dw_writel(dw, name, val)	__raw_writel((val), &(dw)->name)
-
-/* Default use SPI0 register for mrst, we will detect Penwell and use SPI1 */
-static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0;
-
-static u32 *pclk_spi0;
-/* Always contains an accessible address, start with 0 */
-static struct dw_spi_reg *pspi;
 
 static struct kmsg_dumper dw_dumper;
 static int dumper_registered;
@@ -116,77 +42,21 @@ static void dw_kmsg_dump(struct kmsg_dumper *dumper,
 	size_t len;
 
 	/* When run to this, we'd better re-init the HW */
-	mrst_early_console_init();
+	mid_spi_early_console_reset();
 
 	while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len))
-		early_mrst_console.write(&early_mrst_console, line, len);
-}
-
-/* Set the ratio rate to 115200, 8n1, IRQ disabled */
-static void max3110_write_config(void)
-{
-	u16 config;
-
-	config = 0xc001;
-	dw_writel(pspi, dr, config);
-}
-
-/* Translate char to a eligible word and send to max3110 */
-static void max3110_write_data(char c)
-{
-	u16 data;
-
-	data = 0x8000 | c;
-	dw_writel(pspi, dr, data);
+		mid_spi_early_console.write(&mid_spi_early_console, line, len);
 }
 
 void mrst_early_console_init(void)
 {
-	u32 ctrlr0 = 0;
-	u32 spi0_cdiv;
-	u32 freq; /* Freqency info only need be searched once */
-
-	/* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */
-	pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
-							MRST_CLK_SPI0_REG);
-	spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
-	freq = 100000000 / (spi0_cdiv + 1);
+	/* Default use SPI0 register for mrst */
+	unsigned long spi_paddr = MRST_REGBASE_SPI0;
 
+	/* Detect Penwell and use SPI1 */
 	if (mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL)
-		mrst_spi_paddr = MRST_REGBASE_SPI1;
-
-	pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
-						mrst_spi_paddr);
-
-	/* Disable SPI controller */
-	dw_writel(pspi, ssienr, 0);
-
-	/* Set control param, 8 bits, transmit only mode */
-	ctrlr0 = dw_readl(pspi, ctrl0);
-
-	ctrlr0 &= 0xfcc0;
-	ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET)
-		      | (SPI_TMOD_TO << SPI_TMOD_OFFSET);
-	dw_writel(pspi, ctrl0, ctrlr0);
-
-	/*
-	 * Change the spi0 clk to comply with 115200 bps, use 100000 to
-	 * calculate the clk dividor to make the clock a little slower
-	 * than real baud rate.
-	 */
-	dw_writel(pspi, baudr, freq/100000);
-
-	/* Disable all INT for early phase */
-	dw_writel(pspi, imr, 0x0);
-
-	/* Set the cs to spi-uart */
-	dw_writel(pspi, ser, 0x2);
-
-	/* Enable the HW, the last step for HW init */
-	dw_writel(pspi, ssienr, 0x1);
-
-	/* Set the default configuration */
-	max3110_write_config();
+		spi_paddr = MRST_REGBASE_SPI1;
+	mid_spi_early_console_init(spi_paddr);
 
 	/* Register the kmsg dumper */
 	if (!dumper_registered) {
@@ -196,48 +66,6 @@ void mrst_early_console_init(void)
 	}
 }
 
-/* Slave select should be called in the read/write function */
-static void early_mrst_spi_putc(char c)
-{
-	unsigned int timeout;
-	u32 sr;
-
-	timeout = MRST_SPI_TIMEOUT;
-	/* Early putc needs to make sure the TX FIFO is not full */
-	while (--timeout) {
-		sr = dw_readl(pspi, sr);
-		if (!(sr & SR_TF_NOT_FULL))
-			cpu_relax();
-		else
-			break;
-	}
-
-	if (!timeout)
-		pr_warning("MRST earlycon: timed out\n");
-	else
-		max3110_write_data(c);
-}
-
-/* Early SPI only uses polling mode */
-static void early_mrst_spi_write(struct console *con, const char *str, unsigned n)
-{
-	int i;
-
-	for (i = 0; i < n && *str; i++) {
-		if (*str == '\n')
-			early_mrst_spi_putc('\r');
-		early_mrst_spi_putc(*str);
-		str++;
-	}
-}
-
-struct console early_mrst_console = {
-	.name =		"earlymrst",
-	.write =	early_mrst_spi_write,
-	.flags =	CON_PRINTBUFFER,
-	.index =	-1,
-};
-
 /*
  * Following is the early console based on Medfield HSU (High
  * Speed UART) device.
drivers/platform/x86/Makefile +2 -0
index bf7e4f9..6e4ff46 100644
@@ -50,3 +50,5 @@ obj-$(CONFIG_INTEL_MID_POWER_BUTTON)	+= intel_mid_powerbtn.o
 obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early/
drivers/platform/x86/early/Makefile new file +5 -0
new file mode 100644
index 0000000..5d9408c
@@ -0,0 +1,5 @@
+#
+# Makefile for linux/drivers/platform/x86/early
+# x86 Platform-Specific Early Printk Support
+#
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID_SPI)	+= intel_mid_spi.o
drivers/platform/x86/early/intel_mid_spi.c new file +220 -0
new file mode 100644
index 0000000..fa5a1a2
@@ -0,0 +1,220 @@
+/*
+ * intel_mid_spi.c - SPI UART early consoles for Intel MID platforms
+ *
+ * Copyright (c) 2008-2012, Intel Corporation
+ *
+ * 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; version 2
+ * of the License.
+ */
+
+/*
+ * This file is originally implemented by Feng Tang <[email protected]>.
+ * It is moved here to co-exist with CONFIG_EARLY_PRINTK_ACPI.
+ * Any questions you should contact the original author.
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/serial_mfd.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/intel_mid_early.h>
+#include <asm/fixmap.h>
+
+#define DW_SPI_TIMEOUT			0x200000
+#define DW_SPI0_CLK_REG			0xff11d86c
+
+/* Bit fields in CTRLR0 */
+#define SPI_DFS_OFFSET			0
+
+#define SPI_FRF_OFFSET			4
+#define SPI_FRF_SPI			0x0
+#define SPI_FRF_SSP			0x1
+#define SPI_FRF_MICROWIRE		0x2
+#define SPI_FRF_RESV			0x3
+
+#define SPI_MODE_OFFSET			6
+#define SPI_SCPH_OFFSET			6
+#define SPI_SCOL_OFFSET			7
+#define SPI_TMOD_OFFSET			8
+#define	SPI_TMOD_TR			0x0		/* xmit & recv */
+#define SPI_TMOD_TO			0x1		/* xmit only */
+#define SPI_TMOD_RO			0x2		/* recv only */
+#define SPI_TMOD_EPROMREAD		0x3		/* eeprom read mode */
+
+#define SPI_SLVOE_OFFSET		10
+#define SPI_SRL_OFFSET			11
+#define SPI_CFS_OFFSET			12
+
+/* Bit fields in SR, 7 bits */
+#define SR_MASK				0x7f		/* cover 7 bits */
+#define SR_BUSY				(1 << 0)
+#define SR_TF_NOT_FULL			(1 << 1)
+#define SR_TF_EMPT			(1 << 2)
+#define SR_RF_NOT_EMPT			(1 << 3)
+#define SR_RF_FULL			(1 << 4)
+#define SR_TX_ERR			(1 << 5)
+#define SR_DCOL				(1 << 6)
+
+struct dw_spi_reg {
+	u32	ctrl0;
+	u32	ctrl1;
+	u32	ssienr;
+	u32	mwcr;
+	u32	ser;
+	u32	baudr;
+	u32	txfltr;
+	u32	rxfltr;
+	u32	txflr;
+	u32	rxflr;
+	u32	sr;
+	u32	imr;
+	u32	isr;
+	u32	risr;
+	u32	txoicr;
+	u32	rxoicr;
+	u32	rxuicr;
+	u32	msticr;
+	u32	icr;
+	u32	dmacr;
+	u32	dmatdlr;
+	u32	dmardlr;
+	u32	idr;
+	u32	version;
+
+	/* Currently operates as 32 bits, though only the low 16 bits matter */
+	u32	dr;
+} __packed;
+
+#define dw_readl(dw, name)		__raw_readl(&(dw)->name)
+#define dw_writel(dw, name, val)	__raw_writel((val), &(dw)->name)
+
+static u32 *pclk_spi0;
+/* Always contains an accessible address, start with 0 */
+static struct dw_spi_reg *pspi;
+static int dw_spi_initialized;
+static u32 dw_spi_regbase;
+
+/* Translate char to a eligible word and send to max3110 */
+static void max3110_write_data(char c)
+{
+	u16 data;
+
+	data = 0x8000 | c;
+	dw_writel(pspi, dr, data);
+}
+
+/* Set the ratio rate to 115200, 8n1, IRQ disabled */
+static void max3110_write_config(void)
+{
+	u16 config;
+
+	config = 0xc001;
+	dw_writel(pspi, dr, config);
+}
+
+int mid_spi_early_console_reset(void)
+{
+	u32 ctrlr0 = 0;
+	u32 spi0_cdiv;
+	u32 freq; /* Freqency info only need be searched once */
+
+	/* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */
+	pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
+						      DW_SPI0_CLK_REG);
+	spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
+	freq = 100000000 / (spi0_cdiv + 1);
+
+	pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
+						 dw_spi_regbase);
+
+	/* Disable SPI controller */
+	dw_writel(pspi, ssienr, 0);
+
+	/* Set control param, 8 bits, transmit only mode */
+	ctrlr0 = dw_readl(pspi, ctrl0);
+
+	ctrlr0 &= 0xfcc0;
+	ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET)
+		      | (SPI_TMOD_TO << SPI_TMOD_OFFSET);
+	dw_writel(pspi, ctrl0, ctrlr0);
+
+	/*
+	 * Change the spi0 clk to comply with 115200 bps, use 100000 to
+	 * calculate the clk dividor to make the clock a little slower
+	 * than real baud rate.
+	 */
+	dw_writel(pspi, baudr, freq/100000);
+
+	/* Disable all INT for early phase */
+	dw_writel(pspi, imr, 0x0);
+
+	/* Set the cs to spi-uart */
+	dw_writel(pspi, ser, 0x2);
+
+	/* Enable the HW, the last step for HW init */
+	dw_writel(pspi, ssienr, 0x1);
+
+	/* Set the default configuration */
+	max3110_write_config();
+
+	return 0;
+}
+EXPORT_SYMBOL(mid_spi_early_console_reset);
+
+/* Slave select should be called in the read/write function */
+static void dw_early_spi_putc(char c)
+{
+	unsigned int timeout;
+	u32 sr;
+
+	timeout = DW_SPI_TIMEOUT;
+	/* Early putc needs to make sure the TX FIFO is not full */
+	while (--timeout) {
+		sr = dw_readl(pspi, sr);
+		if (!(sr & SR_TF_NOT_FULL))
+			cpu_relax();
+		else
+			break;
+	}
+
+	if (!timeout)
+		pr_warn("mid-spi-early: timed out\n");
+	else
+		max3110_write_data(c);
+}
+
+/* Early SPI only uses polling mode */
+static void dw_early_spi_write(struct console *con,
+			       const char *str, unsigned n)
+{
+	int i;
+
+	for (i = 0; i < n && *str; i++) {
+		if (*str == '\n')
+			dw_early_spi_putc('\r');
+		dw_early_spi_putc(*str);
+		str++;
+	}
+}
+
+struct console mid_spi_early_console = {
+	.name =		"earlymidspi",
+	.write =	dw_early_spi_write,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
+};
+
+void __init mid_spi_early_console_init(u32 spi_paddr)
+{
+	if (dw_spi_initialized)
+		return;
+	dw_spi_regbase = spi_paddr;
+	mid_spi_early_console_reset();
+	dw_spi_initialized = 1;
+}
+
include/acpi/actbl2.h +1 -0
index 1b2b356..ffa9d62 100644
@@ -341,6 +341,7 @@ struct acpi_dbg2_device {
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_INTEL_MID_SPI     0x0002
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
include/linux/intel_mid_early.h new file +12 -0
new file mode 100644
index 0000000..edba232
@@ -0,0 +1,12 @@
+#ifndef LINUX_INTEL_MID_EARLY_H
+#define LINUX_INTEL_MID_EARLY_H
+
+#include <linux/console.h>
+
+extern struct console mid_spi_early_console;
+
+extern void mid_spi_early_console_init(u32 spi_paddr);
+extern int mid_spi_early_console_reset(void);
+
+#endif /* LINUX_INTEL_MID_EARLY_H */
+
Signature · 7 lines
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
author
#34 lore raw

RE: [PATCH v5 2/2] ACPI: Add Intel MID SPI early console support.

Quoted 3 lines
Quoted 1 line

earlyprintk=acpi

.. or earlyprintk=mrst
?

ACK.
The two launchers are all workable for MID_SPI. I'll add more comments and resend this patch. Thanks

author NAK
#35 lore raw

RE: [PATCH v5 2/2] ACPI: Add Intel MID SPI early console support.

In reply to Konrad Rzeszutek Wilk
Quoted 5 lines

arch/x86/kernel/early_printk.c static inline void early_console_register(struct console *con, int keep_early) · line 211

Quoted 4 lines
arch/x86/kernel/early_printk.c +4 -0
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+	if (info->port_type == ACPI_DBG2_SERIAL_PORT
+	    && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+	    && info->register_count > 0) {

Is it ever going to be zero?

NAK.
No register base definition (buggy BIOS?) is meaningless for ACPI launched MID_SPI earlycon.

Thanks and best regards/Lv Zheng