* [PATCH v2 1/6] include: Add defines for SBI debug console extension
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
2022-11-23 10:57 ` [PATCH v2 2/6] lib: sbi: Add sbi_nputs() function Anup Patel
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 UTC (permalink / raw)
To: opensbi
We add SBI debug console extension related defines/enum to the
SBI ecall interface header.
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_ecall_interface.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index a3f2bf4..1dd3874 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,9 @@ 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_PUTS 0x0
+
/* 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] 9+ messages in thread* [PATCH v2 2/6] lib: sbi: Add sbi_nputs() function
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
2022-11-23 10:57 ` [PATCH v2 1/6] include: Add defines for SBI debug console extension Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
2022-11-23 10:57 ` [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 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 | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/include/sbi/sbi_console.h b/include/sbi/sbi_console.h
index e15b55d..1bdeeb9 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);
+void 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 cfef2f8..a975708 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -51,6 +51,16 @@ void sbi_puts(const char *str)
spin_unlock(&console_out_lock);
}
+void 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);
+}
+
void sbi_gets(char *s, int maxwidth, char endchar)
{
int ch;
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
2022-11-23 10:57 ` [PATCH v2 1/6] include: Add defines for SBI debug console extension Anup Patel
2022-11-23 10:57 ` [PATCH v2 2/6] lib: sbi: Add sbi_nputs() function Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
2022-11-23 13:58 ` Xiang W
2022-11-23 10:57 ` [PATCH v2 4/6] lib: sbi: Implement SBI debug console extension Anup Patel
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 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>
---
include/sbi/sbi_domain.h | 15 +++++++++++++
lib/sbi/sbi_domain.c | 47 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 5553d21..4afcc37 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -154,6 +154,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 f24a8e5..6d19d2c 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -195,6 +195,24 @@ 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 int sanitize_domain(const struct sbi_platform *plat,
struct sbi_domain *dom)
{
@@ -303,6 +321,35 @@ 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 pos = 0;
+ const struct sbi_domain_memregion *reg;
+
+ if (!dom)
+ return FALSE;
+
+ while (pos < size) {
+ reg = find_region(dom, addr + pos);
+ if (!reg)
+ return FALSE;
+
+ if (!sbi_domain_check_addr(dom, addr + pos,
+ mode, access_flags))
+ return FALSE;
+
+ if (reg->order < __riscv_xlen)
+ pos += 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] 9+ messages in thread* [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function
2022-11-23 10:57 ` [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
@ 2022-11-23 13:58 ` Xiang W
2022-11-23 15:44 ` Anup Patel
0 siblings, 1 reply; 9+ messages in thread
From: Xiang W @ 2022-11-23 13:58 UTC (permalink / raw)
To: opensbi
? 2022-11-23???? 16:27 +0530?Anup Patel???
> 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>
> ---
> ?include/sbi/sbi_domain.h | 15 +++++++++++++
> ?lib/sbi/sbi_domain.c???? | 47 ++++++++++++++++++++++++++++++++++++++++
> ?2 files changed, 62 insertions(+)
>
> diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> index 5553d21..4afcc37 100644
> --- a/include/sbi/sbi_domain.h
> +++ b/include/sbi/sbi_domain.h
> @@ -154,6 +154,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 f24a8e5..6d19d2c 100644
> --- a/lib/sbi/sbi_domain.c
> +++ b/lib/sbi/sbi_domain.c
> @@ -195,6 +195,24 @@ 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 int sanitize_domain(const struct sbi_platform *plat,
> ?????????????????????????? struct sbi_domain *dom)
> ?{
> @@ -303,6 +321,35 @@ 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 pos = 0;
> +???????const struct sbi_domain_memregion *reg;
> +
> +???????if (!dom)
> +???????????????return FALSE;
> +
> +???????while (pos < size) {
> +???????????????reg = find_region(dom, addr + pos);
> +???????????????if (!reg)
> +???????????????????????return FALSE;
> +
> +???????????????if (!sbi_domain_check_addr(dom, addr + pos,
> +????????????????????????????????????????? mode, access_flags))
> +???????????????????????return FALSE;
> +
> +???????????????if (reg->order < __riscv_xlen)
> +???????????????????????pos += 1UL << reg->order;
addr+pos not always point to the beginning of the region, so the size of the
region cannot be added directly.
suggestion:
pos = reg->base + (1 << reg->order) - addr
Regards,
Xiang W
> +???????????????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 [flat|nested] 9+ messages in thread* [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function
2022-11-23 13:58 ` Xiang W
@ 2022-11-23 15:44 ` Anup Patel
0 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 15:44 UTC (permalink / raw)
To: opensbi
On Wed, Nov 23, 2022 at 7:30 PM Xiang W <wxjstz@126.com> wrote:
>
> ? 2022-11-23???? 16:27 +0530?Anup Patel???
> > 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>
> > ---
> > include/sbi/sbi_domain.h | 15 +++++++++++++
> > lib/sbi/sbi_domain.c | 47 ++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 62 insertions(+)
> >
> > diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> > index 5553d21..4afcc37 100644
> > --- a/include/sbi/sbi_domain.h
> > +++ b/include/sbi/sbi_domain.h
> > @@ -154,6 +154,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 f24a8e5..6d19d2c 100644
> > --- a/lib/sbi/sbi_domain.c
> > +++ b/lib/sbi/sbi_domain.c
> > @@ -195,6 +195,24 @@ 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 int sanitize_domain(const struct sbi_platform *plat,
> > struct sbi_domain *dom)
> > {
> > @@ -303,6 +321,35 @@ 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 pos = 0;
> > + const struct sbi_domain_memregion *reg;
> > +
> > + if (!dom)
> > + return FALSE;
> > +
> > + while (pos < size) {
> > + reg = find_region(dom, addr + pos);
> > + if (!reg)
> > + return FALSE;
> > +
> > + if (!sbi_domain_check_addr(dom, addr + pos,
> > + mode, access_flags))
> > + return FALSE;
> > +
> > + if (reg->order < __riscv_xlen)
> > + pos += 1UL << reg->order;
> addr+pos not always point to the beginning of the region, so the size of the
> region cannot be added directly.
>
> suggestion:
> pos = reg->base + (1 << reg->order) - addr
This loop seems to be broken for overlapping regions.
What you are suggesting will also not work for overlapping regions.
Let me rethink.
Regards,
Anup
>
> Regards,
> Xiang W
> > + else
> > + break;
> > + }
> > +
> > + return TRUE;
> > +}
> > +
> > void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
> > {
> > u32 i, k;
> > --
> > 2.34.1
> >
> >
>
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 4/6] lib: sbi: Implement SBI debug console extension
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
` (2 preceding siblings ...)
2022-11-23 10:57 ` [PATCH v2 3/6] lib: sbi: Add sbi_domain_check_addr_range() function Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
2022-11-23 10:57 ` [PATCH v2 5/6] lib: sbi: Add console_puts() callback in the console device Anup Patel
2022-11-23 10:57 ` [PATCH v2 6/6] lib: utils/serial: Implement console_puts() for semihosting Anup Patel
5 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 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>
---
lib/sbi/Kconfig | 4 +++
lib/sbi/objects.mk | 3 ++
lib/sbi/sbi_ecall_dbcn.c | 62 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 69 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..19ac021
--- /dev/null
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+ if (funcid == SBI_EXT_DBCN_CONSOLE_PUTS) {
+ /*
+ * 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_EINVALID_ADDR;
+ sbi_nputs((const char *)regs->a1, regs->a0);
+ return 0;
+ }
+
+ 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] 9+ messages in thread* [PATCH v2 5/6] lib: sbi: Add console_puts() callback in the console device
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
` (3 preceding siblings ...)
2022-11-23 10:57 ` [PATCH v2 4/6] lib: sbi: Implement SBI debug console extension Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
2022-11-23 10:57 ` [PATCH v2 6/6] lib: utils/serial: Implement console_puts() for semihosting Anup Patel
5 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 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>
---
include/sbi/sbi_console.h | 3 +++
lib/sbi/sbi_console.c | 19 ++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/include/sbi/sbi_console.h b/include/sbi/sbi_console.h
index 1bdeeb9..7e757a7 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 */
+ void (*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 a975708..3c98f4e 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;
@@ -44,9 +45,13 @@ void sbi_putc(char ch)
void sbi_puts(const char *str)
{
spin_lock(&console_out_lock);
- while (*str) {
- sbi_putc(*str);
- str++;
+ if (console_dev && console_dev->console_puts) {
+ console_dev->console_puts(str, sbi_strlen(str));
+ } else {
+ while (*str) {
+ sbi_putc(*str);
+ str++;
+ }
}
spin_unlock(&console_out_lock);
}
@@ -56,8 +61,12 @@ void 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]);
+ if (console_dev && console_dev->console_puts) {
+ console_dev->console_puts(str, len);
+ } else {
+ for (i = 0; i < len; i++)
+ sbi_putc(str[i]);
+ }
spin_unlock(&console_out_lock);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 6/6] lib: utils/serial: Implement console_puts() for semihosting
2022-11-23 10:57 [PATCH v2 0/6] OpenSBI debug console support Anup Patel
` (4 preceding siblings ...)
2022-11-23 10:57 ` [PATCH v2 5/6] lib: sbi: Add console_puts() callback in the console device Anup Patel
@ 2022-11-23 10:57 ` Anup Patel
5 siblings, 0 replies; 9+ messages in thread
From: Anup Patel @ 2022-11-23 10:57 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>
---
lib/utils/serial/semihosting.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/lib/utils/serial/semihosting.c b/lib/utils/serial/semihosting.c
index 86fa296..773b75e 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,20 @@ static void semihosting_putc(char ch)
semihosting_trap(SYSWRITEC, &ch);
}
+static void semihosting_puts(const char *str, unsigned long len)
+{
+ char ch;
+ unsigned long i;
+
+ if (semihosting_outfd < 0) {
+ for (i = 0; i < len; i++) {
+ ch = str[i];
+ semihosting_trap(SYSWRITEC, &ch);
+ }
+ } else
+ semihosting_write(semihosting_outfd, str, len);
+}
+
static int semihosting_getc(void)
{
char ch = 0;
@@ -165,12 +196,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] 9+ messages in thread