diff mbox series

[kvm-unit-tests,4/3] riscv: Support using SBI DBCN for the console

Message ID 20250322091640.161511-2-andrew.jones@linux.dev (mailing list archive)
State New
Headers show
Series riscv: Improved bare metal support | expand

Commit Message

Andrew Jones March 22, 2025, 9:16 a.m. UTC
We don't want to add support for lots of UARTs nor lots of support
for UARTs. Thankfully SBI may have the DBCN extension, allowing us
to use that instead when our simple UART support is insufficient.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 configure      | 17 +++++++++++------
 lib/riscv/io.c | 16 ++++++++++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/configure b/configure
index 06532a89f9c7..52904d3aa45b 100755
--- a/configure
+++ b/configure
@@ -31,6 +31,7 @@  gen_se_header=
 enable_dump=no
 page_size=
 earlycon=
+console=
 efi=
 efi_direct=
 
@@ -78,7 +79,7 @@  usage() {
 	                           4k [default], 16k, 64k for arm64.
 	                           4k [default], 64k for ppc64.
 	    --earlycon=EARLYCON
-				   Specify the UART name, type and address (optional).
+	                           Specify the UART name, type and address used for the earlycon (optional).
 	                           The specified address will overwrite the UART address set by
 	                           the --target option. EARLYCON can be one of (case sensitive):
 	               uart[8250],mmio,ADDR
@@ -89,6 +90,9 @@  usage() {
 	                           Specify a PL011 compatible UART at address ADDR. Supported
 	                           register stride is 32 bit only.
 	                           (arm/arm64 and riscv32/riscv64 only)
+	    --console=CONSOLE
+	                           Specify the device used for output (optional).
+	               sbi         Use SBI DBCN (riscv only)
 	    --[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 and arm64 only)
 	    --[enable|disable]-werror
 	                           Select whether to compile with the -Werror compiler flag
@@ -175,6 +179,9 @@  while [[ $optno -le $argc ]]; do
 	--earlycon)
 	    earlycon="$arg"
 	    ;;
+	--console)
+	    console="$arg"
+	    ;;
 	--enable-efi)
 	    efi=y
 	    ;;
@@ -503,10 +510,8 @@  cat <<EOF >> lib/config.h
 
 EOF
 elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
-cat <<EOF >> lib/config.h
-
-#define CONFIG_UART_EARLY_BASE ${uart_early_addr}
-
-EOF
+    echo "#define CONFIG_UART_EARLY_BASE ${uart_early_addr}" >> lib/config.h
+    [ "$console" = "sbi" ] && echo "#define CONFIG_SBI_CONSOLE" >> lib/config.h
+    echo >> lib/config.h
 fi
 echo "#endif" >> lib/config.h
diff --git a/lib/riscv/io.c b/lib/riscv/io.c
index 011b5b1dc1d4..c8ebfa1c7bb8 100644
--- a/lib/riscv/io.c
+++ b/lib/riscv/io.c
@@ -6,6 +6,7 @@ 
  * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
  */
 #include <libcflat.h>
+#include <bitops.h>
 #include <config.h>
 #include <devicetree.h>
 #include <asm/io.h>
@@ -29,6 +30,7 @@  static u32 uart0_reg_shift = 1;
 static u32 uart0_reg_width = 1;
 static struct spinlock uart_lock;
 
+#ifndef CONFIG_SBI_CONSOLE
 static u32 uart0_read(u32 num)
 {
 	u32 offset = num << uart0_reg_shift;
@@ -52,6 +54,7 @@  static void uart0_write(u32 num, u32 val)
 	else
 		writel(val, uart0_base + offset);
 }
+#endif
 
 static void uart0_init_fdt(void)
 {
@@ -113,6 +116,18 @@  void io_init(void)
 	}
 }
 
+#ifdef CONFIG_SBI_CONSOLE
+void puts(const char *s)
+{
+	phys_addr_t addr = virt_to_phys((void *)s);
+	unsigned long hi = upper_32_bits(addr);
+	unsigned long lo = lower_32_bits(addr);
+
+	spin_lock(&uart_lock);
+	sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, strlen(s), lo, hi, 0, 0, 0);
+	spin_unlock(&uart_lock);
+}
+#else
 void puts(const char *s)
 {
 	spin_lock(&uart_lock);
@@ -123,6 +138,7 @@  void puts(const char *s)
 	}
 	spin_unlock(&uart_lock);
 }
+#endif
 
 /*
  * Defining halt to take 'code' as an argument guarantees that it will