git: d2dea8b46a8a - main - arm: Add EARLY_PRINTF for ns8250 on arm/aarch64 platforms.

From: Michal Meloun <mmel_at_FreeBSD.org>
Date: Sun, 22 Feb 2026 21:21:15 UTC
The branch main has been updated by mmel:

URL: https://cgit.FreeBSD.org/src/commit/?id=d2dea8b46a8a61359c5185f4af3cc1761139bcb4

commit d2dea8b46a8a61359c5185f4af3cc1761139bcb4
Author:     Michal Meloun <mmel@FreeBSD.org>
AuthorDate: 2025-02-02 14:22:34 +0000
Commit:     Michal Meloun <mmel@FreeBSD.org>
CommitDate: 2026-02-22 21:13:33 +0000

    arm: Add EARLY_PRINTF for ns8250 on arm/aarch64 platforms.
    
    Reviewed  by:   adrian (previous version)
    MFC after:      3 weeks
---
 sys/conf/options               |  4 ++++
 sys/dev/uart/uart_dev_ns8250.c | 42 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/sys/conf/options b/sys/conf/options
index d5192db59181..4aeb15a489ea 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -1016,3 +1016,7 @@ PRESERVE_EARLY_KENV	opt_global.h
 
 # Options for the Intel QuickAssist (QAT) driver
 QAT_DISABLE_SAFE_DC_MODE	opt_qat.h
+
+# EARLY_PRINTF specific options fo NS8250 uart
+UART_NS8250_EARLY_REG_IO_WIDTH	opt_uart.h
+UART_NS8250_EARLY_REG_SHIFT	opt_uart.h
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index c38d50e54ad8..b0c7cd4b44e1 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -89,9 +89,7 @@ SYSCTL_INT(_hw, OID_AUTO, uart_noise_threshold, CTLFLAG_RWTUN,
  * options EARLY_PRINTF=ns8250
 */
 #if CHECK_EARLY_PRINTF(ns8250)
-#if !(defined(__amd64__) || defined(__i386__))
-#error ns8250 early putc is x86 specific as it uses inb/outb
-#endif
+#if (defined(__amd64__) || defined(__i386__))
 static void
 uart_ns8250_early_putc(int c)
 {
@@ -103,7 +101,45 @@ uart_ns8250_early_putc(int c)
 		continue;
 	outb(tx, c);
 }
+#elif (defined(__arm__) || defined(__aarch64__))
+#ifndef UART_NS8250_EARLY_REG_IO_WIDTH
+#error Option 'UART_NS8250_EARLY_REG_IO_WIDTH' is missing.
+#endif
+#ifndef UART_NS8250_EARLY_REG_SHIFT
+#error Option 'UART_NS8250_EARLY_REG_SHIFT' is missing.
+#endif
+
+#if UART_NS8250_EARLY_REG_IO_WIDTH == 1
+#define T uint8_t
+#elif UART_NS8250_EARLY_REG_IO_WIDTH == 2
+#define T uint16_t
+#elif UART_NS8250_EARLY_REG_IO_WIDTH == 4
+#define T uint32_t
+
+#else
+#error Invalid/unsupported UART_NS8250_EARLY_REG_IO_WIDTH value
+#endif
+
+#include <machine/machdep.h>
+
+static void
+uart_ns8250_early_putc(int c)
+{
+	volatile T *stat;
+	volatile T *tx;
+
+	stat = (T *)(socdev_va + (REG_LSR << UART_NS8250_EARLY_REG_SHIFT));
+	tx = (T *)(socdev_va + (REG_DATA << UART_NS8250_EARLY_REG_SHIFT));
+
+	while ((*stat & LSR_THRE) == 0)
+		continue;
+	*tx =  c & 0xff;
+}
+#else
+#error ns8250 early putc is not implemented for current architecture
+#endif
 early_putc_t *early_putc = uart_ns8250_early_putc;
+#undef DTYPE
 #endif /* EARLY_PRINTF */
 
 /*