All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: grub-devel@gnu.org
Cc: Daniel Kiper <dkiper@net-space.pl>
Subject: [PATCH v3 6/8] ns8250: Use ACPI SPCR table when available to configure serial
Date: Fri, 23 Dec 2022 12:47:57 +1100	[thread overview]
Message-ID: <20221223014759.2112747-7-benh@kernel.crashing.org> (raw)
In-Reply-To: <20221223014759.2112747-1-benh@kernel.crashing.org>

From: Benjamin Herrenschmidt <benh@amazon.com>

"serial auto" is now equivalent to just "serial" and will use the
SPCR to discover the port if present, otherwise defaults to "com0"
as before.

This allows to support MMIO ports specified by ACPI which is needed
on AWS EC2 "metal" instances, and will enable GRUB to pickup the
port configuration specified by ACPI in other cases.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 docs/grub.texi               |  9 ++++
 grub-core/Makefile.core.def  |  1 +
 grub-core/term/ns8250-spcr.c | 83 ++++++++++++++++++++++++++++++++++++
 grub-core/term/serial.c      | 21 ++++++---
 include/grub/serial.h        |  1 +
 5 files changed, 110 insertions(+), 5 deletions(-)
 create mode 100644 grub-core/term/ns8250-spcr.c

diff --git a/docs/grub.texi b/docs/grub.texi
index 50c811a88..fd22a69fa 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -2719,6 +2719,10 @@ you want to use COM2, you must specify @samp{--unit=1} instead. This
 command accepts many other options, so please refer to @ref{serial},
 for more details.
 
+Without argument or with @samp{--port=auto}, GRUB will attempt to use
+ACPI when available to auto-detect the default serial port and its
+configuration.
+
 The commands @command{terminal_input} (@pxref{terminal_input}) and
 @command{terminal_output} (@pxref{terminal_output}) choose which type of
 terminal you want to use. In the case above, the terminal will be a
@@ -4172,6 +4176,11 @@ be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
 bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd},
 @samp{even} and defaults to @samp{no}.
 
+If passed no @var{unit} nor @var{port}, or if @var{port} is set to
+@samp{auto} then GRUB will attempt to use ACPI to automatically detect
+the system default serial port and its configuration. If this information
+is not available, it will default to @var{unit} 0.
+
 The serial port is not used as a communication channel unless the
 @command{terminal_input} or @command{terminal_output} command is used
 (@pxref{terminal_input}, @pxref{terminal_output}).
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 95942fc8c..b656bdb44 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2048,6 +2048,7 @@ module = {
   name = serial;
   common = term/serial.c;
   x86 = term/ns8250.c;
+  x86 = term/ns8250-spcr.c;
   ieee1275 = term/ieee1275/serial.c;
   mips_arc = term/arc/serial.c;
   efi = term/efi/serial.c;
diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c
new file mode 100644
index 000000000..0b4417a30
--- /dev/null
+++ b/grub-core/term/ns8250-spcr.c
@@ -0,0 +1,83 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/serial.h>
+#include <grub/ns8250.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/acpi.h>
+
+char *
+grub_ns8250_spcr_init (void)
+{
+  struct grub_acpi_spcr *spcr;
+  struct grub_serial_config config;
+
+  spcr = grub_acpi_find_table (GRUB_ACPI_SPCR_SIGNATURE);
+  if (spcr == NULL)
+    return NULL;
+  if (spcr->hdr.revision < 2)
+    return NULL;
+  if (spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550 &&
+      spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550X)
+    return NULL;
+  /* For now, we only support byte accesses */
+  if (spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_BYTE &&
+      spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_LGCY)
+    return NULL;
+  config.word_len = 8;
+  config.parity = GRUB_SERIAL_PARITY_NONE;
+  config.stop_bits = GRUB_SERIAL_STOP_BITS_1;
+  config.base_clock = UART_DEFAULT_BASE_CLOCK;
+  if (spcr->flow_control & GRUB_ACPI_SPCR_FC_RTSCTS)
+    config.rtscts = 1;
+  else
+    config.rtscts = 0;
+  switch (spcr->baud_rate)
+    {
+      case GRUB_ACPI_SPCR_BAUD_9600:
+        config.speed = 9600;
+        break;
+      case GRUB_ACPI_SPCR_BAUD_19200:
+        config.speed = 19200;
+        break;
+      case GRUB_ACPI_SPCR_BAUD_57600:
+        config.speed = 57600;
+        break;
+      case GRUB_ACPI_SPCR_BAUD_115200:
+        config.speed = 115200;
+        break;
+      case GRUB_ACPI_SPCR_BAUD_CURRENT:
+      default:
+       /*
+        * We don't (yet) have a way to read the currently
+        * configured speed in HW, so let's use a sane default
+        */
+        config.speed = 115200;
+        break;
+    };
+  switch (spcr->base_addr.space_id)
+    {
+      case GRUB_ACPI_GENADDR_MEM_SPACE:
+        return grub_serial_ns8250_add_mmio (spcr->base_addr.addr, &config);
+      case GRUB_ACPI_GENADDR_IO_SPACE:
+        return grub_serial_ns8250_add_port (spcr->base_addr.addr, &config);
+      default:
+        return NULL;
+    };
+}
diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c
index cdbbc54e3..d49261b48 100644
--- a/grub-core/term/serial.c
+++ b/grub-core/term/serial.c
@@ -157,12 +157,23 @@ grub_serial_find (const char *name)
     {
       name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1],
 							0, 16), NULL);
-      if (!name)
-	return NULL;
+      if (name == NULL)
+        return NULL;
 
       FOR_SERIAL_PORTS (port)
-	if (grub_strcmp (port->name, name) == 0)
-	  break;
+        if (grub_strcmp (port->name, name) == 0)
+           break;
+    }
+  if (!port && grub_strcmp (name, "auto") == 0)
+    {
+      /* Look for an SPCR if any. If not, default to com0 */
+      name = grub_ns8250_spcr_init ();
+      if (name == NULL)
+        name = "com0";
+
+      FOR_SERIAL_PORTS (port)
+        if (grub_strcmp (port->name, name) == 0)
+          break;
     }
 #endif
 
@@ -210,7 +221,7 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args)
     name = args[0];
 
   if (!name)
-    name = "com0";
+    name = "auto";
 
   port = grub_serial_find (name);
   if (!port)
diff --git a/include/grub/serial.h b/include/grub/serial.h
index a94327140..8d6ed56a3 100644
--- a/include/grub/serial.h
+++ b/include/grub/serial.h
@@ -185,6 +185,7 @@ grub_serial_config_defaults (struct grub_serial_port *port)
 
 #if defined(__mips__) || defined (__i386__) || defined (__x86_64__)
 void grub_ns8250_init (void);
+char *grub_ns8250_spcr_init (void);
 char *grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config *config);
 char *grub_serial_ns8250_add_mmio (grub_addr_t addr, struct grub_serial_config *config);
 #endif
-- 
2.34.1



  parent reply	other threads:[~2022-12-23  1:49 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-23  1:47 [PATCH v2 0/8] serial: Add MMIO & SPCR support Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 1/8] acpi: Export a generic grub_acpi_find_table Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 2/8] acpi: Add SPCR and generic address definitions Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 3/8] ns8250: Add base support for MMIO UARTs Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 4/8] ns8250: Move base clock definition to a header Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 5/8] ns8250: Add configuration parameter when adding ports Benjamin Herrenschmidt
2022-12-23  1:47 ` Benjamin Herrenschmidt [this message]
2022-12-23  1:47 ` [PATCH v3 7/8] ns8250: Support more MMIO access sizes Benjamin Herrenschmidt
2022-12-23  1:47 ` [PATCH v3 8/8] serial: Add ability to specify MMIO ports via 'serial' Benjamin Herrenschmidt
2023-01-12 12:51 ` [PATCH v2 0/8] serial: Add MMIO & SPCR support Daniel Kiper
2023-01-19 17:31   ` Daniel Kiper
2023-01-20  6:15     ` Benjamin Herrenschmidt
2023-02-09 14:44       ` Daniel Kiper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221223014759.2112747-7-benh@kernel.crashing.org \
    --to=benh@kernel.crashing.org \
    --cc=dkiper@net-space.pl \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.