lib: sbi: Implement SBI debug console extension
authorAnup Patel <apatel@ventanamicro.com>
Wed, 23 Nov 2022 05:41:43 +0000 (11:11 +0530)
committerAnup Patel <anup@brainfault.org>
Fri, 10 Feb 2023 04:25:18 +0000 (09:55 +0530)
We implement SBI debug console extension as one of the replacement
SBI extensions. This extension is only available when OpenSBI platform
provides a console device to generic library.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
lib/sbi/Kconfig
lib/sbi/objects.mk
lib/sbi/sbi_ecall_dbcn.c [new file with mode: 0644]

index df74bba..ef6728b 100644 (file)
@@ -26,6 +26,10 @@ config SBI_ECALL_PMU
        bool "Performance Monitoring Unit extension"
        default y
 
+config SBI_ECALL_DBCN
+       bool "Debug Console extension"
+       default y
+
 config SBI_ECALL_LEGACY
        bool "SBI v0.1 legacy extensions"
        default y
index c774ebb..319f38d 100644 (file)
@@ -37,6 +37,9 @@ libsbi-objs-$(CONFIG_SBI_ECALL_SRST) += sbi_ecall_srst.o
 carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_PMU) += ecall_pmu
 libsbi-objs-$(CONFIG_SBI_ECALL_PMU) += sbi_ecall_pmu.o
 
+carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_DBCN) += ecall_dbcn
+libsbi-objs-$(CONFIG_SBI_ECALL_DBCN) += sbi_ecall_dbcn.o
+
 carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_LEGACY) += ecall_legacy
 libsbi-objs-$(CONFIG_SBI_ECALL_LEGACY) += sbi_ecall_legacy.o
 
diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
new file mode 100644 (file)
index 0000000..fe7e175
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *   Anup Patel <apatel@ventanamicro.com>
+ */
+
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_domain.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_ecall.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_trap.h>
+#include <sbi/riscv_asm.h>
+
+static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
+                                 const struct sbi_trap_regs *regs,
+                                 unsigned long *out_val,
+                                 struct sbi_trap_info *out_trap)
+{
+       ulong smode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >>
+                       MSTATUS_MPP_SHIFT;
+
+       switch (funcid) {
+       case SBI_EXT_DBCN_CONSOLE_WRITE:
+       case SBI_EXT_DBCN_CONSOLE_READ:
+               /*
+                * On RV32, the M-mode can only access the first 4GB of
+                * the physical address space because M-mode does not have
+                * MMU to access full 34-bit physical address space.
+                *
+                * Based on above, we simply fail if the upper 32bits of
+                * the physical address (i.e. a2 register) is non-zero on
+                * RV32.
+                */
+#if __riscv_xlen == 32
+               if (regs->a2)
+                       return SBI_ERR_FAILED;
+#endif
+               if (!sbi_domain_check_addr_range(sbi_domain_thishart_ptr(),
+                                       regs->a1, regs->a0, smode,
+                                       SBI_DOMAIN_READ|SBI_DOMAIN_WRITE))
+                       return SBI_ERR_INVALID_PARAM;
+               if (funcid == SBI_EXT_DBCN_CONSOLE_WRITE)
+                       *out_val = sbi_nputs((const char *)regs->a1, regs->a0);
+               else
+                       *out_val = sbi_ngets((char *)regs->a1, regs->a0);
+               return 0;
+       case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
+               sbi_putc(regs->a0);
+               return 0;
+       default:
+               break;
+       }
+
+       return SBI_ENOTSUPP;
+}
+
+static int sbi_ecall_dbcn_probe(unsigned long extid, unsigned long *out_val)
+{
+       *out_val = sbi_console_get_device() ? 1 : 0;
+       return 0;
+}
+
+struct sbi_ecall_extension ecall_dbcn = {
+       .extid_start = SBI_EXT_DBCN,
+       .extid_end = SBI_EXT_DBCN,
+       .handle = sbi_ecall_dbcn_handler,
+       .probe = sbi_ecall_dbcn_probe,
+};