OpenSBI Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/8] OpenSBI debug console support
@ 2023-02-10  5:46 Anup Patel
  2023-02-10  5:46 ` [PATCH v6 1/8] include: Add defines for SBI debug console extension Anup Patel
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

The latest proposal of SBI debug console extension can be found at:
https://lists.riscv.org/g/tech-prs/message/96

This series implements SBI debug console support in OpenSBI
as-per above draft proposal.

To test these patches corresponding Linux patches can be found in
riscv_sbi_dbcn_v1 branch at: https://github.com/avpatel/linux.git

These patches can also be found in riscv_sbi_dbcn_v6 branch at:
https://github.com/avpatel/opensbi.git

Changes since v5:
 - Rebased on latest OpenSBI sources
 - Updated Reviewed-by tags
 - Addressed Drew's comments in all patches
 - Updated SBI debug console implementation as-per latest proposal
   where console write() is non-blocking.

Changes since v4:
 - Rebased on latest OpenSBI sources
 - Updated Reviewed-by tags
 - Added new PATCH8 to speed-up sbi_printf() using nputs()

Changes since v3:
 - Rebased on OpenSBI v1.2 release
 - Updated Reviewed-by tags
 - Added new PATCH3 for sbi_ngets() function
 - Updated SBI debug console implementation in PATCH5 as-per latest
   proposal having both console write() and read() functions.

Changes since v2:
 - Reworked sbi_domain_check_addr_range() in PATCH3 to make it work
   for overlapping regions.

Changes since v1:
 - New PATCH3 to implement sbi_domain_check_addr_range() function
 - Added checks in PATCH4 for location and size of string to print
 - New PATCH5 to add console_puts() callback in the console device
 - New PATCH6 to implement console_puts() for semihosting

Anup Patel (8):
  include: Add defines for SBI debug console extension
  lib: sbi: Add sbi_nputs() function
  lib: sbi: Add sbi_ngets() function
  lib: sbi: Add sbi_domain_check_addr_range() function
  lib: sbi: Implement SBI debug console extension
  lib: sbi: Add console_puts() callback in the console device
  lib: utils/serial: Implement console_puts() for semihosting
  lib: sbi: Speed-up sbi_printf() and friends using nputs()

 include/sbi/sbi_console.h         |  7 +++
 include/sbi/sbi_domain.h          | 15 ++++++
 include/sbi/sbi_ecall_interface.h |  6 +++
 lib/sbi/Kconfig                   |  4 ++
 lib/sbi/objects.mk                |  3 ++
 lib/sbi/sbi_console.c             | 88 ++++++++++++++++++++++++++++---
 lib/sbi/sbi_domain.c              | 69 ++++++++++++++++++++++++
 lib/sbi/sbi_ecall_dbcn.c          | 72 +++++++++++++++++++++++++
 lib/utils/serial/semihosting.c    | 37 +++++++++++++
 9 files changed, 294 insertions(+), 7 deletions(-)
 create mode 100644 lib/sbi/sbi_ecall_dbcn.c

-- 
2.34.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v6 1/8] include: Add defines for SBI debug console extension
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 2/8] lib: sbi: Add sbi_nputs() function Anup Patel
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We add SBI debug console extension related defines to the
SBI ecall interface header.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
---
 include/sbi/sbi_ecall_interface.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index a3f2bf4..9d6f474 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -29,6 +29,7 @@
 #define SBI_EXT_HSM				0x48534D
 #define SBI_EXT_SRST				0x53525354
 #define SBI_EXT_PMU				0x504D55
+#define SBI_EXT_DBCN				0x4442434E
 
 /* SBI function IDs for BASE extension*/
 #define SBI_EXT_BASE_GET_SPEC_VERSION		0x0
@@ -230,6 +231,11 @@ enum sbi_pmu_ctr_type {
 /* Flags defined for counter stop function */
 #define SBI_PMU_STOP_FLAG_RESET (1 << 0)
 
+/* SBI function IDs for DBCN extension */
+#define SBI_EXT_DBCN_CONSOLE_WRITE		0x0
+#define SBI_EXT_DBCN_CONSOLE_READ		0x1
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE		0x2
+
 /* SBI base specification related macros */
 #define SBI_SPEC_VERSION_MAJOR_OFFSET		24
 #define SBI_SPEC_VERSION_MAJOR_MASK		0x7f
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 2/8] lib: sbi: Add sbi_nputs() function
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
  2023-02-10  5:46 ` [PATCH v6 1/8] include: Add defines for SBI debug console extension Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 3/8] lib: sbi: Add sbi_ngets() function Anup Patel
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We add new sbi_nputs() which help us print a fixed number of characters
from a physical memory location.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
---
 include/sbi/sbi_console.h |  2 ++
 lib/sbi/sbi_console.c     | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/include/sbi/sbi_console.h b/include/sbi/sbi_console.h
index e15b55d..dd6a905 100644
--- a/include/sbi/sbi_console.h
+++ b/include/sbi/sbi_console.h
@@ -33,6 +33,8 @@ void sbi_putc(char ch);
 
 void sbi_puts(const char *str);
 
+unsigned long sbi_nputs(const char *str, unsigned long len);
+
 void sbi_gets(char *s, int maxwidth, char endchar);
 
 int __printf(2, 3) sbi_sprintf(char *out, const char *format, ...);
diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index bb6e1ef..2f83a26 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -51,6 +51,18 @@ void sbi_puts(const char *str)
 	spin_unlock(&console_out_lock);
 }
 
+unsigned long sbi_nputs(const char *str, unsigned long len)
+{
+	unsigned long i;
+
+	spin_lock(&console_out_lock);
+	for (i = 0; i < len; i++)
+		sbi_putc(str[i]);
+	spin_unlock(&console_out_lock);
+
+	return i;
+}
+
 void sbi_gets(char *s, int maxwidth, char endchar)
 {
 	int ch;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 3/8] lib: sbi: Add sbi_ngets() function
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
  2023-02-10  5:46 ` [PATCH v6 1/8] include: Add defines for SBI debug console extension Anup Patel
  2023-02-10  5:46 ` [PATCH v6 2/8] lib: sbi: Add sbi_nputs() function Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 4/8] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We add new sbi_ngets() which help us read characters into a
physical memory location.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 include/sbi/sbi_console.h |  2 ++
 lib/sbi/sbi_console.c     | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/sbi/sbi_console.h b/include/sbi/sbi_console.h
index dd6a905..3c1f5e5 100644
--- a/include/sbi/sbi_console.h
+++ b/include/sbi/sbi_console.h
@@ -37,6 +37,8 @@ unsigned long sbi_nputs(const char *str, unsigned long len);
 
 void sbi_gets(char *s, int maxwidth, char endchar);
 
+unsigned long sbi_ngets(char *str, unsigned long len);
+
 int __printf(2, 3) sbi_sprintf(char *out, const char *format, ...);
 
 int __printf(3, 4) sbi_snprintf(char *out, u32 out_sz, const char *format, ...);
diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 2f83a26..c734bc0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -76,6 +76,21 @@ void sbi_gets(char *s, int maxwidth, char endchar)
 	*retval = '\0';
 }
 
+unsigned long sbi_ngets(char *str, unsigned long len)
+{
+	int ch;
+	unsigned long i;
+
+	for (i = 0; i < len; i++) {
+		ch = sbi_getc();
+		if (ch < 0)
+			break;
+		str[i] = ch;
+	}
+
+	return i;
+}
+
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 4/8] lib: sbi: Add sbi_domain_check_addr_range() function
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (2 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 3/8] lib: sbi: Add sbi_ngets() function Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 5/8] lib: sbi: Implement SBI debug console extension Anup Patel
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We add sbi_domain_check_addr_range() helper function to check
whether a given address range is accessible under a particular
domain.

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>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 include/sbi/sbi_domain.h | 15 +++++++++
 lib/sbi/sbi_domain.c     | 69 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index bbb3eff..ab1a944 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -196,6 +196,21 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom,
 			   unsigned long addr, unsigned long mode,
 			   unsigned long access_flags);
 
+/**
+ * Check whether we can access specified address range for given mode and
+ * memory region flags under a domain
+ * @param dom pointer to domain
+ * @param addr the start of the address range to be checked
+ * @param size the size of the address range to be checked
+ * @param mode the privilege mode of access
+ * @param access_flags bitmask of domain access types (enum sbi_domain_access)
+ * @return TRUE if access allowed otherwise FALSE
+ */
+bool sbi_domain_check_addr_range(const struct sbi_domain *dom,
+				 unsigned long addr, unsigned long size,
+				 unsigned long mode,
+				 unsigned long access_flags);
+
 /** Dump domain details on the console */
 void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix);
 
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 3813f1b..dc825b0 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -212,6 +212,44 @@ static bool is_region_before(const struct sbi_domain_memregion *regA,
 	return false;
 }
 
+static const struct sbi_domain_memregion *find_region(
+						const struct sbi_domain *dom,
+						unsigned long addr)
+{
+	unsigned long rstart, rend;
+	struct sbi_domain_memregion *reg;
+
+	sbi_domain_for_each_memregion(dom, reg) {
+		rstart = reg->base;
+		rend = (reg->order < __riscv_xlen) ?
+			rstart + ((1UL << reg->order) - 1) : -1UL;
+		if (rstart <= addr && addr <= rend)
+			return reg;
+	}
+
+	return NULL;
+}
+
+static const struct sbi_domain_memregion *find_next_subset_region(
+				const struct sbi_domain *dom,
+				const struct sbi_domain_memregion *reg,
+				unsigned long addr)
+{
+	struct sbi_domain_memregion *sreg, *ret = NULL;
+
+	sbi_domain_for_each_memregion(dom, sreg) {
+		if (sreg == reg || (sreg->base <= addr) ||
+		    !is_region_subset(sreg, reg))
+			continue;
+
+		if (!ret || (sreg->base < ret->base) ||
+		    ((sreg->base == ret->base) && (sreg->order < ret->order)))
+			ret = sreg;
+	}
+
+	return ret;
+}
+
 static int sanitize_domain(const struct sbi_platform *plat,
 			   struct sbi_domain *dom)
 {
@@ -320,6 +358,37 @@ static int sanitize_domain(const struct sbi_platform *plat,
 	return 0;
 }
 
+bool sbi_domain_check_addr_range(const struct sbi_domain *dom,
+				 unsigned long addr, unsigned long size,
+				 unsigned long mode,
+				 unsigned long access_flags)
+{
+	unsigned long max = addr + size;
+	const struct sbi_domain_memregion *reg, *sreg;
+
+	if (!dom)
+		return false;
+
+	while (addr < max) {
+		reg = find_region(dom, addr);
+		if (!reg)
+			return false;
+
+		if (!sbi_domain_check_addr(dom, addr, mode, access_flags))
+			return false;
+
+		sreg = find_next_subset_region(dom, reg, addr);
+		if (sreg)
+			addr = sreg->base;
+		else if (reg->order < __riscv_xlen)
+			addr = reg->base + (1UL << reg->order);
+		else
+			break;
+	}
+
+	return true;
+}
+
 void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
 {
 	u32 i, k;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 5/8] lib: sbi: Implement SBI debug console extension
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (3 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 4/8] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 6/8] lib: sbi: Add console_puts() callback in the console device Anup Patel
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

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          |  4 +++
 lib/sbi/objects.mk       |  3 ++
 lib/sbi/sbi_ecall_dbcn.c | 72 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)
 create mode 100644 lib/sbi/sbi_ecall_dbcn.c

diff --git a/lib/sbi/Kconfig b/lib/sbi/Kconfig
index df74bba..ef6728b 100644
--- a/lib/sbi/Kconfig
+++ b/lib/sbi/Kconfig
@@ -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
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index c774ebb..319f38d 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -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
index 0000000..fe7e175
--- /dev/null
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -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,
+};
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 6/8] lib: sbi: Add console_puts() callback in the console device
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (4 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 5/8] lib: sbi: Implement SBI debug console extension Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 7/8] lib: utils/serial: Implement console_puts() for semihosting Anup Patel
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We add console_puts() callback in the console device which allows
console drivers (such as semihosting) to implement a specialized
way to output character string.

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>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 include/sbi/sbi_console.h |  3 +++
 lib/sbi/sbi_console.c     | 29 ++++++++++++++++++++++-------
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/include/sbi/sbi_console.h b/include/sbi/sbi_console.h
index 3c1f5e5..0979765 100644
--- a/include/sbi/sbi_console.h
+++ b/include/sbi/sbi_console.h
@@ -19,6 +19,9 @@ struct sbi_console_device {
 	/** Write a character to the console output */
 	void (*console_putc)(char ch);
 
+	/** Write a character string to the console output */
+	unsigned long (*console_puts)(const char *str, unsigned long len);
+
 	/** Read a character from the console input */
 	int (*console_getc)(void);
 };
diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index c734bc0..8a5d9de 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -12,6 +12,7 @@
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
+#include <sbi/sbi_string.h>
 
 static const struct sbi_console_device *console_dev = NULL;
 static spinlock_t console_out_lock	       = SPIN_LOCK_INITIALIZER;
@@ -43,24 +44,38 @@ void sbi_putc(char ch)
 
 void sbi_puts(const char *str)
 {
+	unsigned long p, len;
+
 	spin_lock(&console_out_lock);
-	while (*str) {
-		sbi_putc(*str);
-		str++;
+	if (console_dev && console_dev->console_puts) {
+		p = 0;
+		len = sbi_strlen(str);
+		while (p < len)
+			p += console_dev->console_puts(&str[p], len - p);
+	} else {
+		while (*str) {
+			sbi_putc(*str);
+			str++;
+		}
 	}
 	spin_unlock(&console_out_lock);
 }
 
 unsigned long sbi_nputs(const char *str, unsigned long len)
 {
-	unsigned long i;
+	unsigned long i, ret;
 
 	spin_lock(&console_out_lock);
-	for (i = 0; i < len; i++)
-		sbi_putc(str[i]);
+	if (console_dev && console_dev->console_puts) {
+		ret = console_dev->console_puts(str, len);
+	} else {
+		for (i = 0; i < len; i++)
+			sbi_putc(str[i]);
+		ret = len;
+	}
 	spin_unlock(&console_out_lock);
 
-	return i;
+	return ret;
 }
 
 void sbi_gets(char *s, int maxwidth, char endchar)
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 7/8] lib: utils/serial: Implement console_puts() for semihosting
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (5 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 6/8] lib: sbi: Add console_puts() callback in the console device Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  5:46 ` [PATCH v6 8/8] lib: sbi: Speed-up sbi_printf() and friends using nputs() Anup Patel
  2023-02-10  7:20 ` [PATCH v6 0/8] OpenSBI debug console support Anup Patel
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

We implement console_puts() for semihosting serial driver to speed-up
semihosting based prints.

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>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 lib/utils/serial/semihosting.c | 37 ++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/lib/utils/serial/semihosting.c b/lib/utils/serial/semihosting.c
index 86fa296..ce65887 100644
--- a/lib/utils/serial/semihosting.c
+++ b/lib/utils/serial/semihosting.c
@@ -15,6 +15,7 @@
 
 #define SYSOPEN     0x01
 #define SYSWRITEC   0x03
+#define SYSWRITE    0x05
 #define SYSREAD     0x06
 #define SYSREADC    0x07
 #define SYSERRNO	0x13
@@ -93,6 +94,7 @@ static int semihosting_errno(void)
 }
 
 static int semihosting_infd = SBI_ENODEV;
+static int semihosting_outfd = SBI_ENODEV;
 
 static long semihosting_open(const char *fname, enum semihosting_open_mode mode)
 {
@@ -141,6 +143,21 @@ static long semihosting_read(long fd, void *memp, size_t len)
 	return len - ret;
 }
 
+static long semihosting_write(long fd, const void *memp, size_t len)
+{
+	long ret;
+	struct semihosting_rdwr_s write;
+
+	write.fd = fd;
+	write.memp = (void *)memp;
+	write.len = len;
+
+	ret = semihosting_trap(SYSWRITE, &write);
+	if (ret < 0)
+		return semihosting_errno();
+	return len - ret;
+}
+
 /* clang-format on */
 
 static void semihosting_putc(char ch)
@@ -148,6 +165,24 @@ static void semihosting_putc(char ch)
 	semihosting_trap(SYSWRITEC, &ch);
 }
 
+static unsigned long semihosting_puts(const char *str, unsigned long len)
+{
+	char ch;
+	long ret;
+	unsigned long i;
+
+	if (semihosting_outfd < 0) {
+		for (i = 0; i < len; i++) {
+			ch = str[i];
+			semihosting_trap(SYSWRITEC, &ch);
+		}
+		ret = len;
+	} else
+		ret = semihosting_write(semihosting_outfd, str, len);
+
+	return (ret < 0) ? 0 : ret;
+}
+
 static int semihosting_getc(void)
 {
 	char ch = 0;
@@ -165,12 +200,14 @@ static int semihosting_getc(void)
 static struct sbi_console_device semihosting_console = {
 	.name = "semihosting",
 	.console_putc = semihosting_putc,
+	.console_puts = semihosting_puts,
 	.console_getc = semihosting_getc
 };
 
 int semihosting_init(void)
 {
 	semihosting_infd = semihosting_open(":tt", MODE_READ);
+	semihosting_outfd = semihosting_open(":tt", MODE_WRITE);
 
 	sbi_console_set_device(&semihosting_console);
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 8/8] lib: sbi: Speed-up sbi_printf() and friends using nputs()
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (6 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 7/8] lib: utils/serial: Implement console_puts() for semihosting Anup Patel
@ 2023-02-10  5:46 ` Anup Patel
  2023-02-10  7:20 ` [PATCH v6 0/8] OpenSBI debug console support Anup Patel
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  5:46 UTC (permalink / raw)
  To: opensbi

The sbi_printf() is slow for semihosting because it prints one
character at a time. To speed-up sbi_printf() for semihosting,
we use a temporary buffer and nputs().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 lib/sbi/sbi_console.c | 76 ++++++++++++++++++++++++++++++-------------
 1 file changed, 54 insertions(+), 22 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 8a5d9de..f3ac003 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,7 +14,11 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define CONSOLE_TBUF_MAX 256
+
 static const struct sbi_console_device *console_dev = NULL;
+static char console_tbuf[CONSOLE_TBUF_MAX];
+static u32 console_tbuf_len;
 static spinlock_t console_out_lock	       = SPIN_LOCK_INITIALIZER;
 
 bool sbi_isprintable(char c)
@@ -42,37 +46,44 @@ void sbi_putc(char ch)
 	}
 }
 
-void sbi_puts(const char *str)
+static unsigned long nputs(const char *str, unsigned long len)
 {
-	unsigned long p, len;
+	unsigned long i, ret;
 
-	spin_lock(&console_out_lock);
 	if (console_dev && console_dev->console_puts) {
-		p = 0;
-		len = sbi_strlen(str);
-		while (p < len)
-			p += console_dev->console_puts(&str[p], len - p);
+		ret = console_dev->console_puts(str, len);
 	} else {
-		while (*str) {
-			sbi_putc(*str);
-			str++;
-		}
+		for (i = 0; i < len; i++)
+			sbi_putc(str[i]);
+		ret = len;
 	}
+
+	return ret;
+}
+
+static void nputs_all(const char *str, unsigned long len)
+{
+	unsigned long p = 0;
+
+	while (p < len)
+		p += nputs(&str[p], len - p);
+}
+
+void sbi_puts(const char *str)
+{
+	unsigned long len = sbi_strlen(str);
+
+	spin_lock(&console_out_lock);
+	nputs_all(str, len);
 	spin_unlock(&console_out_lock);
 }
 
 unsigned long sbi_nputs(const char *str, unsigned long len)
 {
-	unsigned long i, ret;
+	unsigned long ret;
 
 	spin_lock(&console_out_lock);
-	if (console_dev && console_dev->console_puts) {
-		ret = console_dev->console_puts(str, len);
-	} else {
-		for (i = 0; i < len; i++)
-			sbi_putc(str[i]);
-		ret = len;
-	}
+	ret = nputs(str, len);
 	spin_unlock(&console_out_lock);
 
 	return ret;
@@ -225,12 +236,30 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 
 static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
-	int width, flags;
-	int pc = 0;
-	char scr[2];
+	int width, flags, pc = 0;
+	char scr[2], *tout;
+	bool use_tbuf = (!out) ? true : false;
 	unsigned long long tmp;
 
+	/*
+	 * The console_tbuf is protected by console_out_lock and
+	 * print() is always called with console_out_lock held
+	 * when out == NULL.
+	 */
+	if (use_tbuf) {
+		console_tbuf_len = CONSOLE_TBUF_MAX;
+		tout = console_tbuf;
+		out = &tout;
+		out_len = &console_tbuf_len;
+	}
+
 	for (; *format != 0; ++format) {
+		if (use_tbuf && !console_tbuf_len) {
+			nputs_all(console_tbuf, CONSOLE_TBUF_MAX);
+			console_tbuf_len = CONSOLE_TBUF_MAX;
+			tout = console_tbuf;
+		}
+
 		if (*format == '%') {
 			++format;
 			width = flags = 0;
@@ -356,6 +385,9 @@ literal:
 		}
 	}
 
+	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
+		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
+
 	return pc;
 }
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 0/8] OpenSBI debug console support
  2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
                   ` (7 preceding siblings ...)
  2023-02-10  5:46 ` [PATCH v6 8/8] lib: sbi: Speed-up sbi_printf() and friends using nputs() Anup Patel
@ 2023-02-10  7:20 ` Anup Patel
  8 siblings, 0 replies; 10+ messages in thread
From: Anup Patel @ 2023-02-10  7:20 UTC (permalink / raw)
  To: opensbi

On Fri, Feb 10, 2023 at 11:17 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> The latest proposal of SBI debug console extension can be found at:
> https://lists.riscv.org/g/tech-prs/message/96
>
> This series implements SBI debug console support in OpenSBI
> as-per above draft proposal.
>
> To test these patches corresponding Linux patches can be found in
> riscv_sbi_dbcn_v1 branch at: https://github.com/avpatel/linux.git
>
> These patches can also be found in riscv_sbi_dbcn_v6 branch at:
> https://github.com/avpatel/opensbi.git
>
> Changes since v5:
>  - Rebased on latest OpenSBI sources
>  - Updated Reviewed-by tags
>  - Addressed Drew's comments in all patches
>  - Updated SBI debug console implementation as-per latest proposal
>    where console write() is non-blocking.
>
> Changes since v4:
>  - Rebased on latest OpenSBI sources
>  - Updated Reviewed-by tags
>  - Added new PATCH8 to speed-up sbi_printf() using nputs()
>
> Changes since v3:
>  - Rebased on OpenSBI v1.2 release
>  - Updated Reviewed-by tags
>  - Added new PATCH3 for sbi_ngets() function
>  - Updated SBI debug console implementation in PATCH5 as-per latest
>    proposal having both console write() and read() functions.
>
> Changes since v2:
>  - Reworked sbi_domain_check_addr_range() in PATCH3 to make it work
>    for overlapping regions.
>
> Changes since v1:
>  - New PATCH3 to implement sbi_domain_check_addr_range() function
>  - Added checks in PATCH4 for location and size of string to print
>  - New PATCH5 to add console_puts() callback in the console device
>  - New PATCH6 to implement console_puts() for semihosting
>
> Anup Patel (8):
>   include: Add defines for SBI debug console extension
>   lib: sbi: Add sbi_nputs() function
>   lib: sbi: Add sbi_ngets() function
>   lib: sbi: Add sbi_domain_check_addr_range() function
>   lib: sbi: Implement SBI debug console extension
>   lib: sbi: Add console_puts() callback in the console device
>   lib: utils/serial: Implement console_puts() for semihosting
>   lib: sbi: Speed-up sbi_printf() and friends using nputs()

Applied this series to the riscv/opensbi repo.

Regards,
Anup

>
>  include/sbi/sbi_console.h         |  7 +++
>  include/sbi/sbi_domain.h          | 15 ++++++
>  include/sbi/sbi_ecall_interface.h |  6 +++
>  lib/sbi/Kconfig                   |  4 ++
>  lib/sbi/objects.mk                |  3 ++
>  lib/sbi/sbi_console.c             | 88 ++++++++++++++++++++++++++++---
>  lib/sbi/sbi_domain.c              | 69 ++++++++++++++++++++++++
>  lib/sbi/sbi_ecall_dbcn.c          | 72 +++++++++++++++++++++++++
>  lib/utils/serial/semihosting.c    | 37 +++++++++++++
>  9 files changed, 294 insertions(+), 7 deletions(-)
>  create mode 100644 lib/sbi/sbi_ecall_dbcn.c
>
> --
> 2.34.1
>


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-02-10  7:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-10  5:46 [PATCH v6 0/8] OpenSBI debug console support Anup Patel
2023-02-10  5:46 ` [PATCH v6 1/8] include: Add defines for SBI debug console extension Anup Patel
2023-02-10  5:46 ` [PATCH v6 2/8] lib: sbi: Add sbi_nputs() function Anup Patel
2023-02-10  5:46 ` [PATCH v6 3/8] lib: sbi: Add sbi_ngets() function Anup Patel
2023-02-10  5:46 ` [PATCH v6 4/8] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
2023-02-10  5:46 ` [PATCH v6 5/8] lib: sbi: Implement SBI debug console extension Anup Patel
2023-02-10  5:46 ` [PATCH v6 6/8] lib: sbi: Add console_puts() callback in the console device Anup Patel
2023-02-10  5:46 ` [PATCH v6 7/8] lib: utils/serial: Implement console_puts() for semihosting Anup Patel
2023-02-10  5:46 ` [PATCH v6 8/8] lib: sbi: Speed-up sbi_printf() and friends using nputs() Anup Patel
2023-02-10  7:20 ` [PATCH v6 0/8] OpenSBI debug console support Anup Patel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox