[kvm-unit-tests PATCH 5/7] riscv: Decouple SBI console from UART init
Xiang W
wangxiang at iscas.ac.cn
Wed Sep 23 20:39:43 PDT 2026
CONFIG_SBI_CONSOLE already routes puts() through SBI DBCN, but console
setup still went through the UART init path. uart0_init_fdt() could skip
a missing UART, while uart0_init_acpi() aborted, so EFI/ACPI guests
with no described UART could not print.
Split the SBI console out of the UART driver. When CONFIG_SBI_CONSOLE is
set, io_init() is a no-op and puts() issues SBI_EXT_DBCN_CONSOLE_WRITE
directly. The UART probe and MMIO path are compiled only when SBI
console is disabled, so ACPI and DT boots no longer depend on an MMIO
UART for output.
Signed-off-by: Xiang W <wangxiang at iscas.ac.cn>
---
lib/riscv/io.c | 50 +++++++++++++++++++++-----------------------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/lib/riscv/io.c b/lib/riscv/io.c
index b1163404..6656cd32 100644
--- a/lib/riscv/io.c
+++ b/lib/riscv/io.c
@@ -14,6 +14,26 @@
#include <asm/setup.h>
#include <asm/spinlock.h>
+static struct spinlock uart_lock;
+
+#ifdef CONFIG_SBI_CONSOLE
+
+void io_init(void)
+{
+}
+
+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
#define UART_LSR_OFFSET 5
#define UART_LSR_THRE 0x20
@@ -28,7 +48,6 @@
static volatile u8 *uart0_base = UART_EARLY_BASE;
static u32 uart0_reg_width = 1;
static u32 uart0_reg_shift;
-static struct spinlock uart_lock;
static u32 uart0_read(u32 num)
{
@@ -71,16 +90,11 @@ static void uart0_init_fdt(void)
break;
}
-#ifdef CONFIG_SBI_CONSOLE
- uart0_base = NULL;
- return;
-#else
if (ret) {
printf("%s: Compatible uart not found in the device tree, aborting...\n",
__func__);
abort();
}
-#endif
} else {
const fdt32_t *val;
int len;
@@ -118,21 +132,7 @@ void io_init(void)
uart0_base, UART_EARLY_BASE);
}
}
-
-void sbi_puts(const char *s);
-void sbi_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);
-}
-
-void uart0_puts(const char *s);
-void uart0_puts(const char *s)
+void puts(const char *s)
{
assert(uart0_base);
spin_lock(&uart_lock);
@@ -143,15 +143,7 @@ void uart0_puts(const char *s)
}
spin_unlock(&uart_lock);
}
-
-void puts(const char *s)
-{
-#ifdef CONFIG_SBI_CONSOLE
- sbi_puts(s);
-#else
- uart0_puts(s);
#endif
-}
/*
* Defining halt to take 'code' as an argument guarantees that it will
--
2.47.3
More information about the kvm-riscv
mailing list