From ajones at ventanamicro.com  Thu Jun  1 00:48:10 2023
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu,  1 Jun 2023 09:48:10 +0200
Subject: [PATCH] lib: sbi: Align system suspend errors with spec
Message-ID: <20230601074810.798131-1-ajones@ventanamicro.com>

The spec says sbi_system_suspend() will return SBI_ERR_INVALID_PARAM
when "sleep_type is reserved or is platform-specific and unimplemented"
and SBI_ERR_NOT_SUPPORTED when sleep_type "is not reserved and is
implemented, but the platform does not support it due to one or more
missing dependencies." Ensure SBI_ERR_INVALID_PARAM is returned for
reserved sleep types and that the system suspend driver can choose
which of the two error types to return itself by returning an error
from its check function rather than a boolean.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/sbi/sbi_system.h |  9 ++++++++-
 lib/sbi/sbi_system.c     | 14 ++++++++------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/include/sbi/sbi_system.h b/include/sbi/sbi_system.h
index 33ff7f1a44a6..0fdcc98cce5d 100644
--- a/include/sbi/sbi_system.h
+++ b/include/sbi/sbi_system.h
@@ -48,7 +48,14 @@ struct sbi_system_suspend_device {
 	/** Name of the system suspend device */
 	char name[32];
 
-	/* Check whether sleep type is supported by the device */
+	/**
+	 * Check whether sleep type is supported by the device
+	 *
+	 * Returns 0 when @sleep_type supported, SBI_ERR_INVALID_PARAM
+	 * when @sleep_type is reserved, or SBI_ERR_NOT_SUPPORTED when
+	 * @sleep_type is not reserved and is implemented, but the
+	 * platform doesn't support it due to missing dependencies.
+	 */
 	int (*system_suspend_check)(u32 sleep_type);
 
 	/**
diff --git a/lib/sbi/sbi_system.c b/lib/sbi/sbi_system.c
index 6933915a12ed..d803ffa84189 100644
--- a/lib/sbi/sbi_system.c
+++ b/lib/sbi/sbi_system.c
@@ -111,7 +111,7 @@ void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev)
 
 static int sbi_system_suspend_test_check(u32 sleep_type)
 {
-	return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND;
+	return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND ? 0 : SBI_EINVAL;
 }
 
 static int sbi_system_suspend_test_suspend(u32 sleep_type,
@@ -142,27 +142,29 @@ void sbi_system_suspend_test_enable(void)
 bool sbi_system_suspend_supported(u32 sleep_type)
 {
 	return suspend_dev && suspend_dev->system_suspend_check &&
-	       suspend_dev->system_suspend_check(sleep_type);
+	       suspend_dev->system_suspend_check(sleep_type) == 0;
 }
 
 int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque)
 {
-	int ret = SBI_ENOTSUPP;
 	const struct sbi_domain *dom = sbi_domain_thishart_ptr();
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 	void (*jump_warmboot)(void) = (void (*)(void))scratch->warmboot_addr;
 	unsigned int hartid = current_hartid();
 	unsigned long prev_mode;
 	unsigned long i;
+	int ret;
 
 	if (!dom || !dom->system_suspend_allowed)
 		return SBI_EFAIL;
 
-	if (!suspend_dev || !suspend_dev->system_suspend)
+	if (!suspend_dev || !suspend_dev->system_suspend ||
+	    !suspend_dev->system_suspend_check)
 		return SBI_EFAIL;
 
-	if (!sbi_system_suspend_supported(sleep_type))
-		return SBI_ENOTSUPP;
+	ret = suspend_dev->system_suspend_check(sleep_type);
+	if (ret != SBI_OK)
+		return ret;
 
 	prev_mode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
 	if (prev_mode != PRV_S && prev_mode != PRV_U)
-- 
2.40.1



From wxjstz at 126.com  Sat Jun  3 08:59:55 2023
From: wxjstz at 126.com (Xiang W)
Date: Sat, 03 Jun 2023 23:59:55 +0800
Subject: [PATCH v2 1/1] lib: utils/ipi: buffer overrun
 aclint_mswi_cold_init
In-Reply-To: <20230529092720.20294-1-heinrich.schuchardt@canonical.com>
References: <20230529092720.20294-1-heinrich.schuchardt@canonical.com>
Message-ID: <bfa17717d010b036cd2ef5bfcc420116cb6a2163.camel@126.com>

? 2023-05-29???? 11:27 +0200?Heinrich Schuchardt???
> The parameter checks in aclint_mswi_cold_init() don't guard against a
> buffer overrun.
> 
> mswi_hartid2data is defined as an array of SBI_HARTMASK_MAX_BITS entries.
> The current check allows
> 
> ??? mswi->hart_count = ACLINT_MSWI_MAX_HARTS
> ??? mswi->first_hartid = SBI_HARTMASK_MAX_BITS - 1.
> 
> With these values mswi_hartid2data will be accessed at index
> 
> ??? SBI_HARTMASK_MAX_BITS + SBI_HARTMASK_MAX_BITS - 2.
> 
> We have to check the sum of mswi->first_hartid and mswi->hart_count.
> 
> Furthermore mswi->hart_count = 0 would not make much sense.
> 
> Addresses-Coverity-ID: 1529705 ("Out-of-bounds write")
> Fixes: 5a049fe1d6a5 ("lib: utils/ipi: Add ACLINT MSWI library")
> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
LGTM

Reviewed-by: Xiang W <wxjstz at 126.com>
> ---
> v2:
> ????????add missing 'Fixes:'
> ---
> ?lib/utils/ipi/aclint_mswi.c | 4 ++--
> ?1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/utils/ipi/aclint_mswi.c b/lib/utils/ipi/aclint_mswi.c
> index 6b004cb..ac8570b 100644
> --- a/lib/utils/ipi/aclint_mswi.c
> +++ b/lib/utils/ipi/aclint_mswi.c
> @@ -75,8 +75,8 @@ int aclint_mswi_cold_init(struct aclint_mswi_data *mswi)
> ????????/* Sanity checks */
> ????????if (!mswi || (mswi->addr & (ACLINT_MSWI_ALIGN - 1)) ||
> ??????????? (mswi->size < (mswi->hart_count * sizeof(u32))) ||
> -?????????? (mswi->first_hartid >= SBI_HARTMASK_MAX_BITS) ||
> -?????????? (mswi->hart_count > ACLINT_MSWI_MAX_HARTS))
> +?????????? (mswi->first_hartid + mswi->hart_count > SBI_HARTMASK_MAX_BITS) ||
> +?????????? (!mswi->hart_count || mswi->hart_count > ACLINT_MSWI_MAX_HARTS))
> ????????????????return SBI_EINVAL;
> ?
> ????????/* Update MSWI hartid table */
> -- 
> 2.39.2
> 
> 



From anup at brainfault.org  Sun Jun  4 02:44:55 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 4 Jun 2023 15:14:55 +0530
Subject: [PATCH v2 1/1] lib: utils/ipi: buffer overrun aclint_mswi_cold_init
In-Reply-To: <20230529092720.20294-1-heinrich.schuchardt@canonical.com>
References: <20230529092720.20294-1-heinrich.schuchardt@canonical.com>
Message-ID: <CAAhSdy3WQY5fwLpv5nKjjMPe0YBgQrPN_Gdq1eNswz8uxecCvA@mail.gmail.com>

On Mon, May 29, 2023 at 2:57?PM Heinrich Schuchardt
<heinrich.schuchardt at canonical.com> wrote:
>
> The parameter checks in aclint_mswi_cold_init() don't guard against a
> buffer overrun.
>
> mswi_hartid2data is defined as an array of SBI_HARTMASK_MAX_BITS entries.
> The current check allows
>
>     mswi->hart_count = ACLINT_MSWI_MAX_HARTS
>     mswi->first_hartid = SBI_HARTMASK_MAX_BITS - 1.
>
> With these values mswi_hartid2data will be accessed at index
>
>     SBI_HARTMASK_MAX_BITS + SBI_HARTMASK_MAX_BITS - 2.
>
> We have to check the sum of mswi->first_hartid and mswi->hart_count.
>
> Furthermore mswi->hart_count = 0 would not make much sense.
>
> Addresses-Coverity-ID: 1529705 ("Out-of-bounds write")
> Fixes: 5a049fe1d6a5 ("lib: utils/ipi: Add ACLINT MSWI library")
> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
> v2:
>         add missing 'Fixes:'
> ---
>  lib/utils/ipi/aclint_mswi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/lib/utils/ipi/aclint_mswi.c b/lib/utils/ipi/aclint_mswi.c
> index 6b004cb..ac8570b 100644
> --- a/lib/utils/ipi/aclint_mswi.c
> +++ b/lib/utils/ipi/aclint_mswi.c
> @@ -75,8 +75,8 @@ int aclint_mswi_cold_init(struct aclint_mswi_data *mswi)
>         /* Sanity checks */
>         if (!mswi || (mswi->addr & (ACLINT_MSWI_ALIGN - 1)) ||
>             (mswi->size < (mswi->hart_count * sizeof(u32))) ||
> -           (mswi->first_hartid >= SBI_HARTMASK_MAX_BITS) ||
> -           (mswi->hart_count > ACLINT_MSWI_MAX_HARTS))
> +           (mswi->first_hartid + mswi->hart_count > SBI_HARTMASK_MAX_BITS) ||
> +           (!mswi->hart_count || mswi->hart_count > ACLINT_MSWI_MAX_HARTS))
>                 return SBI_EINVAL;
>
>         /* Update MSWI hartid table */
> --
> 2.39.2
>


From anup at brainfault.org  Sun Jun  4 02:52:46 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 4 Jun 2023 15:22:46 +0530
Subject: [PATCH] lib: sbi: Align system suspend errors with spec
In-Reply-To: <20230601074810.798131-1-ajones@ventanamicro.com>
References: <20230601074810.798131-1-ajones@ventanamicro.com>
Message-ID: <CAAhSdy33+k2MyV_kZtL6VvVvUXka+pZmY0SOtbZNSMALkgpa5g@mail.gmail.com>

On Thu, Jun 1, 2023 at 1:18?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> The spec says sbi_system_suspend() will return SBI_ERR_INVALID_PARAM
> when "sleep_type is reserved or is platform-specific and unimplemented"
> and SBI_ERR_NOT_SUPPORTED when sleep_type "is not reserved and is
> implemented, but the platform does not support it due to one or more
> missing dependencies." Ensure SBI_ERR_INVALID_PARAM is returned for
> reserved sleep types and that the system suspend driver can choose
> which of the two error types to return itself by returning an error
> from its check function rather than a boolean.
>
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  include/sbi/sbi_system.h |  9 ++++++++-
>  lib/sbi/sbi_system.c     | 14 ++++++++------
>  2 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/include/sbi/sbi_system.h b/include/sbi/sbi_system.h
> index 33ff7f1a44a6..0fdcc98cce5d 100644
> --- a/include/sbi/sbi_system.h
> +++ b/include/sbi/sbi_system.h
> @@ -48,7 +48,14 @@ struct sbi_system_suspend_device {
>         /** Name of the system suspend device */
>         char name[32];
>
> -       /* Check whether sleep type is supported by the device */
> +       /**
> +        * Check whether sleep type is supported by the device
> +        *
> +        * Returns 0 when @sleep_type supported, SBI_ERR_INVALID_PARAM
> +        * when @sleep_type is reserved, or SBI_ERR_NOT_SUPPORTED when
> +        * @sleep_type is not reserved and is implemented, but the
> +        * platform doesn't support it due to missing dependencies.
> +        */
>         int (*system_suspend_check)(u32 sleep_type);
>
>         /**
> diff --git a/lib/sbi/sbi_system.c b/lib/sbi/sbi_system.c
> index 6933915a12ed..d803ffa84189 100644
> --- a/lib/sbi/sbi_system.c
> +++ b/lib/sbi/sbi_system.c
> @@ -111,7 +111,7 @@ void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev)
>
>  static int sbi_system_suspend_test_check(u32 sleep_type)
>  {
> -       return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND;
> +       return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND ? 0 : SBI_EINVAL;
>  }
>
>  static int sbi_system_suspend_test_suspend(u32 sleep_type,
> @@ -142,27 +142,29 @@ void sbi_system_suspend_test_enable(void)
>  bool sbi_system_suspend_supported(u32 sleep_type)
>  {
>         return suspend_dev && suspend_dev->system_suspend_check &&
> -              suspend_dev->system_suspend_check(sleep_type);
> +              suspend_dev->system_suspend_check(sleep_type) == 0;
>  }
>
>  int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque)
>  {
> -       int ret = SBI_ENOTSUPP;
>         const struct sbi_domain *dom = sbi_domain_thishart_ptr();
>         struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
>         void (*jump_warmboot)(void) = (void (*)(void))scratch->warmboot_addr;
>         unsigned int hartid = current_hartid();
>         unsigned long prev_mode;
>         unsigned long i;
> +       int ret;
>
>         if (!dom || !dom->system_suspend_allowed)
>                 return SBI_EFAIL;
>
> -       if (!suspend_dev || !suspend_dev->system_suspend)
> +       if (!suspend_dev || !suspend_dev->system_suspend ||
> +           !suspend_dev->system_suspend_check)
>                 return SBI_EFAIL;
>
> -       if (!sbi_system_suspend_supported(sleep_type))
> -               return SBI_ENOTSUPP;
> +       ret = suspend_dev->system_suspend_check(sleep_type);
> +       if (ret != SBI_OK)
> +               return ret;
>
>         prev_mode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
>         if (prev_mode != PRV_S && prev_mode != PRV_U)
> --
> 2.40.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From anup at brainfault.org  Sun Jun  4 03:17:34 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 4 Jun 2023 15:47:34 +0530
Subject: [PATCH 02/17] lib: sbi: Introduce simple heap allocator
In-Reply-To: <20230531-6b1fc211b6c567e1ae1d5f3a@orel>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-3-apatel@ventanamicro.com> <20230531-6b1fc211b6c567e1ae1d5f3a@orel>
Message-ID: <CAAhSdy2+_VO_i4wkoh7sXTa9ouv3RgyTtOePa6ozxHqcwcC-Ng@mail.gmail.com>

On Wed, May 31, 2023 at 5:41?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Tue, Apr 25, 2023 at 06:02:15PM +0530, Anup Patel wrote:
> > We provide simple heap allocator to manage the heap space provided
> > by OpenSBI firmware and platform.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  include/sbi/sbi_heap.h |  44 +++++++++
> >  lib/sbi/objects.mk     |   1 +
> >  lib/sbi/sbi_heap.c     | 204 +++++++++++++++++++++++++++++++++++++++++
> >  lib/sbi/sbi_init.c     |  15 +++
> >  4 files changed, 264 insertions(+)
> >  create mode 100644 include/sbi/sbi_heap.h
> >  create mode 100644 lib/sbi/sbi_heap.c
> >
> > diff --git a/include/sbi/sbi_heap.h b/include/sbi/sbi_heap.h
> > new file mode 100644
> > index 0000000..88d176e
> > --- /dev/null
> > +++ b/include/sbi/sbi_heap.h
> > @@ -0,0 +1,44 @@
> > +/*
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2023 Ventana Micro Systems Inc.
> > + *
> > + * Authors:
> > + *   Anup Patel<apatel at ventanamicro.com>
> > + */
> > +
> > +#ifndef __SBI_HEAP_H__
> > +#define __SBI_HEAP_H__
> > +
> > +#include <sbi/sbi_types.h>
> > +
> > +struct sbi_scratch;
> > +
> > +/** Allocate from heap area */
> > +void *sbi_malloc(size_t size);
> > +
> > +/** Zero allocate from heap area */
> > +void *sbi_zalloc(size_t size);
> > +
> > +/** Allocate array from heap area */
> > +static inline void *sbi_calloc(size_t nitems, size_t size)
> > +{
> > +     return sbi_zalloc(nitems * size);
> > +}
> > +
> > +/** Free-up to heap area */
> > +void sbi_free(void *ptr);
> > +
> > +/** Amount (in bytes) of free space in the heap area */
> > +unsigned long sbi_heap_free_space(void);
> > +
> > +/** Amount (in bytes) of used space in the heap area */
> > +unsigned long sbi_heap_used_space(void);
> > +
> > +/** Amount (in bytes) of reserved space in the heap area */
> > +unsigned long sbi_heap_reserved_space(void);
> > +
> > +/** Initialize heap area */
> > +int sbi_heap_init(struct sbi_scratch *scratch);
> > +
> > +#endif
> > diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
> > index 7d691c6..c699187 100644
> > --- a/lib/sbi/objects.mk
> > +++ b/lib/sbi/objects.mk
> > @@ -59,6 +59,7 @@ libsbi-objs-y += sbi_domain.o
> >  libsbi-objs-y += sbi_emulate_csr.o
> >  libsbi-objs-y += sbi_fifo.o
> >  libsbi-objs-y += sbi_hart.o
> > +libsbi-objs-y += sbi_heap.o
> >  libsbi-objs-y += sbi_math.o
> >  libsbi-objs-y += sbi_hfence.o
> >  libsbi-objs-y += sbi_hsm.o
> > diff --git a/lib/sbi/sbi_heap.c b/lib/sbi/sbi_heap.c
> > new file mode 100644
> > index 0000000..82aa1ec
> > --- /dev/null
> > +++ b/lib/sbi/sbi_heap.c
> > @@ -0,0 +1,204 @@
> > +/*
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2023 Ventana Micro Systems Inc.
> > + *
> > + * Authors:
> > + *   Anup Patel<apatel at ventanamicro.com>
> > + */
> > +
> > +#include <sbi/riscv_locks.h>
> > +#include <sbi/sbi_error.h>
> > +#include <sbi/sbi_heap.h>
> > +#include <sbi/sbi_list.h>
> > +#include <sbi/sbi_scratch.h>
> > +#include <sbi/sbi_string.h>
> > +
> > +#define HEAP_BASE_ALIGN                      1024
> > +#define HEAP_ALLOC_ALIGN             64
>
> What's the rationale for these alignments. Maybe alloc-align is expected
> cache size? But what about base-align? Can you add comment explaining
> them?

The HEAP_BASE_ALIGN is used to ensure that the base address
and size of the heap is 1KB aligned.

Also, the HEAP_ALLOC_ALIGN should be roughly the same as
cache-line size. For now this is fixed, but in the future, platform
might be able to provide cache line size.

Okay, I will add comments.

>
> > +#define HEAP_HOUSEKEEPING_FACTOR     16
> > +
> > +struct heap_node {
> > +     struct sbi_dlist head;
> > +     unsigned long addr;
> > +     unsigned long size;
> > +};
> > +
> > +struct heap_control {
> > +     spinlock_t lock;
> > +     unsigned long base;
> > +     unsigned long size;
> > +     unsigned long hkbase;
> > +     unsigned long hksize;
> > +     struct sbi_dlist free_node_list;
> > +     struct sbi_dlist free_space_list;
> > +     struct sbi_dlist used_space_list;
> > +};
> > +
> > +static struct heap_control hpctrl;
> > +
> > +void *sbi_malloc(size_t size)
> > +{
> > +     void *ret = NULL;
> > +     struct heap_node *n, *np;
> > +
> > +     if (!size)
> > +             return NULL;
> > +
> > +     size += HEAP_ALLOC_ALIGN - 1;
> > +     size &= ~((unsigned long)HEAP_ALLOC_ALIGN - 1);
> > +
> > +     spin_lock(&hpctrl.lock);
> > +
> > +     np = NULL;
> > +     sbi_list_for_each_entry(n, &hpctrl.free_space_list, head) {
> > +             if (size <= n->size) {
> > +                     np = n;
> > +                     break;
> > +             }
> > +     }
> > +     if (np) {
> > +             if ((size < np->size) &&
> > +                 !sbi_list_empty(&hpctrl.free_node_list)) {
> > +                     n = sbi_list_first_entry(&hpctrl.free_node_list,
> > +                                              struct heap_node, head);
> > +                     sbi_list_del(&n->head);
> > +                     n->addr = np->addr + np->size - size;
> > +                     n->size = size;
> > +                     np->size -= size;
> > +                     sbi_list_add_tail(&n->head, &hpctrl.used_space_list);
> > +                     ret = (void *)n->addr;
> > +             } else if (size == np->size) {
> > +                     sbi_list_del(&np->head);
> > +                     sbi_list_add_tail(&np->head, &hpctrl.used_space_list);
> > +                     ret = (void *)np->addr;
> > +             }
> > +     }
> > +
> > +     spin_unlock(&hpctrl.lock);
> > +
> > +     return ret;
> > +}
> > +
> > +void *sbi_zalloc(size_t size)
> > +{
> > +     void *ret = sbi_malloc(size);
> > +
> > +     if (ret)
> > +             sbi_memset(ret, 0, size);
> > +     return ret;
> > +}
> > +
> > +void sbi_free(void *ptr)
> > +{
> > +     struct heap_node *n, *np;
> > +
> > +     if (!ptr)
> > +             return;
> > +
> > +     spin_lock(&hpctrl.lock);
> > +
> > +     np = NULL;
> > +     sbi_list_for_each_entry(n, &hpctrl.used_space_list, head) {
> > +             if ((n->addr <= (unsigned long)ptr) &&
> > +                 ((unsigned long)ptr < (n->addr + n->size))) {
> > +                     np = n;
> > +                     break;
> > +             }
> > +     }
> > +     if (!np) {
> > +             spin_unlock(&hpctrl.lock);
> > +             return;
> > +     }
> > +
> > +     sbi_list_del(&np->head);
> > +
> > +     sbi_list_for_each_entry(n, &hpctrl.free_space_list, head) {
> > +             if ((np->addr + np->size) == n->addr) {
> > +                     n->addr = np->addr;
> > +                     n->size += np->size;
> > +                     sbi_list_add_tail(&np->head, &hpctrl.free_node_list);
> > +                     np = NULL;
> > +                     break;
> > +             } else if (np->addr == (n->addr + n->size)) {
> > +                     n->size += np->size;
> > +                     sbi_list_add_tail(&np->head, &hpctrl.free_node_list);
> > +                     np = NULL;
> > +                     break;
> > +             } else if ((n->addr + n->size) < np->addr) {
> > +                     sbi_list_add(&np->head, &n->head);
> > +                     np = NULL;
> > +                     break;
> > +             }
> > +     }
> > +     if (np)
> > +             sbi_list_add_tail(&np->head, &hpctrl.free_space_list);
> > +
> > +     spin_unlock(&hpctrl.lock);
> > +}
> > +
> > +unsigned long sbi_heap_free_space(void)
> > +{
> > +     struct heap_node *n;
> > +     unsigned long ret = 0;
> > +
> > +     spin_lock(&hpctrl.lock);
> > +     sbi_list_for_each_entry(n, &hpctrl.free_space_list, head)
> > +             ret += n->size;
> > +     spin_unlock(&hpctrl.lock);
> > +
> > +     return ret;
> > +}
> > +
> > +unsigned long sbi_heap_used_space(void)
> > +{
> > +     return hpctrl.size - hpctrl.hksize - sbi_heap_free_space();
> > +}
> > +
> > +unsigned long sbi_heap_reserved_space(void)
> > +{
> > +     return hpctrl.hksize;
> > +}
> > +
> > +int sbi_heap_init(struct sbi_scratch *scratch)
> > +{
> > +     unsigned long i;
> > +     struct heap_node *n;
> > +
> > +     /* Sanity checks on heap offset and size */
> > +     if (!scratch->fw_heap_size ||
> > +         (scratch->fw_heap_size & (HEAP_BASE_ALIGN - 1)) ||
> > +         (scratch->fw_heap_offset < scratch->fw_rw_offset) ||
> > +         (scratch->fw_size < (scratch->fw_heap_offset + scratch->fw_heap_size)) ||
> > +         (scratch->fw_heap_offset & (HEAP_BASE_ALIGN - 1)))
> > +             return SBI_EINVAL;
> > +
> > +     /* Initialize heap control */
> > +     SPIN_LOCK_INIT(hpctrl.lock);
> > +     hpctrl.base = scratch->fw_start + scratch->fw_heap_offset;
> > +     hpctrl.size = scratch->fw_heap_size;
> > +     hpctrl.hkbase = hpctrl.base;
> > +     hpctrl.hksize = hpctrl.size / HEAP_HOUSEKEEPING_FACTOR;
> > +     hpctrl.hksize &= ~((unsigned long)HEAP_BASE_ALIGN - 1);
> > +     SBI_INIT_LIST_HEAD(&hpctrl.free_node_list);
> > +     SBI_INIT_LIST_HEAD(&hpctrl.free_space_list);
> > +     SBI_INIT_LIST_HEAD(&hpctrl.used_space_list);
> > +
> > +     /* Prepare free node list */
> > +     for (i = 0; i < (hpctrl.hksize / sizeof(*n)); i++) {
> > +             n = (struct heap_node *)(hpctrl.hkbase + (sizeof(*n) * i));
> > +             SBI_INIT_LIST_HEAD(&n->head);
> > +             n->addr = n->size = 0;
> > +             sbi_list_add_tail(&n->head, &hpctrl.free_node_list);
> > +     }
> > +
> > +     /* Prepare free space list */
> > +     n = sbi_list_first_entry(&hpctrl.free_node_list,
> > +                              struct heap_node, head);
> > +     sbi_list_del(&n->head);
> > +     n->addr = hpctrl.hkbase + hpctrl.hksize;
> > +     n->size = hpctrl.size - hpctrl.hksize;
> > +     sbi_list_add_tail(&n->head, &hpctrl.free_space_list);
> > +
> > +     return 0;
> > +}
> > diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> > index 5db8e7f..f09a7ac 100644
> > --- a/lib/sbi/sbi_init.c
> > +++ b/lib/sbi/sbi_init.c
> > @@ -17,6 +17,7 @@
> >  #include <sbi/sbi_ecall.h>
> >  #include <sbi/sbi_hart.h>
> >  #include <sbi/sbi_hartmask.h>
> > +#include <sbi/sbi_heap.h>
> >  #include <sbi/sbi_hsm.h>
> >  #include <sbi/sbi_ipi.h>
> >  #include <sbi/sbi_irqchip.h>
> > @@ -118,6 +119,15 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
> >       sbi_printf("Firmware Size             : %d KB\n",
> >                  (u32)(scratch->fw_size / 1024));
> >       sbi_printf("Firmware RW Offset        : 0x%lx\n", scratch->fw_rw_offset);
> > +     sbi_printf("Firmware RW Size          : %d KB\n",
> > +                (u32)((scratch->fw_size - scratch->fw_rw_offset) / 1024));
> > +     sbi_printf("Firmware Heap Offset      : 0x%lx\n", scratch->fw_heap_offset);
> > +     sbi_printf("Firmware Heap Size        : "
> > +                "%d KB (total), %d KB (reserved), %d KB (used), %d KB (free)\n",
> > +                (u32)(scratch->fw_heap_size / 1024),
> > +                (u32)(sbi_heap_reserved_space() / 1024),
> > +                (u32)(sbi_heap_used_space() / 1024),
> > +                (u32)(sbi_heap_free_space() / 1024));
> >
> >       /* SBI details */
> >       sbi_printf("Runtime SBI Version       : %d.%d\n",
> > @@ -258,6 +268,11 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
> >               sbi_hart_hang();
> >
> >       /* Note: This has to be second thing in coldboot init sequence */
> > +     rc = sbi_heap_init(scratch);
> > +     if (rc)
> > +             sbi_hart_hang();
> > +
> > +     /* Note: This has to be thing thing in coldboot init sequence */
>
> ...be the third thing...

Okay, I will update.

>
> >       rc = sbi_domain_init(scratch, hartid);
> >       if (rc)
> >               sbi_hart_hang();
> > --
> > 2.34.1
> >
>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>
> Thanks,
> drew

Regards,
Anup


From anup at brainfault.org  Sun Jun  4 03:38:27 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 4 Jun 2023 16:08:27 +0530
Subject: [PATCH 06/17] lib: sbi: Use scratch space to save per-HART domain pointer
In-Reply-To: <20230531-ace2a06252786f57e7952f36@orel>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-7-apatel@ventanamicro.com> <20230531-ace2a06252786f57e7952f36@orel>
Message-ID: <CAAhSdy2iMLH-k7Wk6FSYZdwA63gBaXAp62C4_RojjAzY-GgK1Q@mail.gmail.com>

On Wed, May 31, 2023 at 6:09?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Tue, Apr 25, 2023 at 06:02:19PM +0530, Anup Patel wrote:
> > Instead of using a global array indexed by hartid, we should use
> > scratch space to save per-HART domain pointer.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  include/sbi/sbi_domain.h |  6 +-----
> >  lib/sbi/sbi_domain.c     | 38 +++++++++++++++++++++++++++++++++++---
> >  2 files changed, 36 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> > index 124ea90..b05bcf4 100644
> > --- a/include/sbi/sbi_domain.h
> > +++ b/include/sbi/sbi_domain.h
> > @@ -129,12 +129,8 @@ struct sbi_domain {
> >  /** The root domain instance */
> >  extern struct sbi_domain root;
> >
> > -/** HART id to domain table */
> > -extern struct sbi_domain *hartid_to_domain_table[];
> > -
> >  /** Get pointer to sbi_domain from HART id */
> > -#define sbi_hartid_to_domain(__hartid) \
> > -     hartid_to_domain_table[__hartid]
> > +struct sbi_domain *sbi_hartid_to_domain(u32 hartid);
> >
> >  /** Get pointer to sbi_domain for current HART */
> >  #define sbi_domain_thishart_ptr() \
> > diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> > index b07d310..531737c 100644
> > --- a/lib/sbi/sbi_domain.c
> > +++ b/lib/sbi/sbi_domain.c
> > @@ -23,7 +23,6 @@
> >   * the array to be null-terminated.
> >   */
> >  struct sbi_domain *domidx_to_domain_table[SBI_DOMAIN_MAX_INDEX + 1] = { 0 };
> > -struct sbi_domain *hartid_to_domain_table[SBI_HARTMASK_MAX_BITS] = { 0 };
> >  static u32 domain_count = 0;
> >  static bool domain_finalized = false;
> >
> > @@ -39,6 +38,32 @@ struct sbi_domain root = {
> >       .fw_region_inited = false,
> >  };
> >
> > +static unsigned long domain_hart_ptr_offset;
> > +
> > +struct sbi_domain *sbi_hartid_to_domain(u32 hartid)
> > +{
> > +     struct sbi_scratch *scratch;
> > +
> > +     scratch = sbi_hartid_to_scratch(hartid);
> > +     if (!scratch || !domain_hart_ptr_offset)
> > +             return NULL;
> > +
> > +     return (void *)(*((ulong *)sbi_scratch_offset_ptr(scratch,
> > +                                                domain_hart_ptr_offset)));
> > +}
> > +
> > +static void update_hartid_to_domain(u32 hartid, struct sbi_domain *dom)
> > +{
> > +     struct sbi_scratch *scratch;
> > +
> > +     scratch = sbi_hartid_to_scratch(hartid);
> > +     if (!scratch)
> > +             return;
> > +
> > +     *((ulong *)sbi_scratch_offset_ptr(scratch, domain_hart_ptr_offset))
> > +                                     = (ulong)dom;
> > +}
> > +
> >  bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid)
> >  {
> >       if (dom)
> > @@ -519,11 +544,11 @@ int sbi_domain_register(struct sbi_domain *dom,
> >               if (!sbi_hartmask_test_hart(i, dom->possible_harts))
> >                       continue;
> >
> > -             tdom = hartid_to_domain_table[i];
> > +             tdom = sbi_hartid_to_domain(i);
> >               if (tdom)
> >                       sbi_hartmask_clear_hart(i,
> >                                       &tdom->assigned_harts);
> > -             hartid_to_domain_table[i] = dom;
> > +             update_hartid_to_domain(i, dom);
> >               sbi_hartmask_set_hart(i, &dom->assigned_harts);
> >
> >               /*
> > @@ -715,9 +740,14 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> >               return SBI_EINVAL;
> >       }
> >
> > +     domain_hart_ptr_offset = sbi_scratch_alloc_offset(sizeof(ulong));
> > +     if (!domain_hart_ptr_offset)
> > +             return SBI_ENOMEM;
> > +
> >       root_memregs = sbi_calloc(sizeof(*root_memregs), ROOT_REGION_MAX + 1);
> >       if (!root_memregs) {
> >               sbi_printf("%s: no memory for root regions\n", __func__);
> > +             sbi_scratch_free_offset(domain_hart_ptr_offset);
> >               return SBI_ENOMEM;
> >       }
> >       root.regions = root_memregs;
> > @@ -726,6 +756,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> >       if (!root_hmask) {
> >               sbi_printf("%s: no memory for root hartmask\n", __func__);
> >               sbi_free(root_memregs);
> > +             sbi_scratch_free_offset(domain_hart_ptr_offset);
> >               return SBI_ENOMEM;
> >       }
> >       root.possible_harts = root_hmask;
> > @@ -774,6 +805,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> >       if (rc) {
> >               sbi_free(root_hmask);
> >               sbi_free(root_memregs);
> > +             sbi_scratch_free_offset(domain_hart_ptr_offset);
> >               return rc;
> >       }
>
> Rather than duplicating all the free()'s we could use a sequence of error
> labels and gotos.

Okay, I will update.

>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>
> Thanks,
> drew

Regards,
Anup


From anup at brainfault.org  Sun Jun  4 04:43:19 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 4 Jun 2023 17:13:19 +0530
Subject: [PATCH 10/17] lib: utils/irqchip: Use heap in PLIC, APLIC and
 IMSIC drivers
In-Reply-To: <20230531-14fb3f8b4bbee3ac09daf364@orel>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-11-apatel@ventanamicro.com> <20230531-14fb3f8b4bbee3ac09daf364@orel>
Message-ID: <CAAhSdy3mUHuvrBKEiWHJovE333tD_DfB-Bjd6gvWwGJ4Cu0Ovg@mail.gmail.com>

On Wed, May 31, 2023 at 6:16?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Tue, Apr 25, 2023 at 06:02:23PM +0530, Anup Patel wrote:
> > Let's use heap allocation in PLIC, APLIC, and IMSIC irqchip drivers
> > instead of using a fixed size global array.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  lib/utils/irqchip/fdt_irqchip_aplic.c | 24 ++++++++++--------
> >  lib/utils/irqchip/fdt_irqchip_imsic.c | 30 +++++++++++-----------
> >  lib/utils/irqchip/fdt_irqchip_plic.c  | 36 +++++++++++++--------------
> >  3 files changed, 47 insertions(+), 43 deletions(-)
> >
> > diff --git a/lib/utils/irqchip/fdt_irqchip_aplic.c b/lib/utils/irqchip/fdt_irqchip_aplic.c
> > index 965f023..caa92a7 100644
> > --- a/lib/utils/irqchip/fdt_irqchip_aplic.c
> > +++ b/lib/utils/irqchip/fdt_irqchip_aplic.c
> > @@ -11,15 +11,11 @@
> >  #include <libfdt.h>
> >  #include <sbi/riscv_asm.h>
> >  #include <sbi/sbi_error.h>
> > +#include <sbi/sbi_heap.h>
> >  #include <sbi_utils/fdt/fdt_helper.h>
> >  #include <sbi_utils/irqchip/fdt_irqchip.h>
> >  #include <sbi_utils/irqchip/aplic.h>
> >
> > -#define APLIC_MAX_NR                 16
> > -
> > -static unsigned long aplic_count = 0;
> > -static struct aplic_data aplic[APLIC_MAX_NR];
> > -
> >  static int irqchip_aplic_warm_init(void)
> >  {
> >       /* Nothing to do here. */
> > @@ -32,15 +28,23 @@ static int irqchip_aplic_cold_init(void *fdt, int nodeoff,
> >       int rc;
> >       struct aplic_data *pd;
> >
> > -     if (APLIC_MAX_NR <= aplic_count)
> > -             return SBI_ENOSPC;
> > -     pd = &aplic[aplic_count++];
> > +     pd = sbi_zalloc(sizeof(*pd));
> > +     if (!pd)
> > +             return SBI_ENOMEM;
> >
> >       rc = fdt_parse_aplic_node(fdt, nodeoff, pd);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(pd);
> >               return rc;
> > +     }
> >
> > -     return aplic_cold_irqchip_init(pd);
> > +     rc = aplic_cold_irqchip_init(pd);
> > +     if (rc) {
> > +             sbi_free(pd);
> > +             return rc;
> > +     }
> > +
> > +     return 0;
> >  }
> >
> >  static const struct fdt_match irqchip_aplic_match[] = {
> > diff --git a/lib/utils/irqchip/fdt_irqchip_imsic.c b/lib/utils/irqchip/fdt_irqchip_imsic.c
> > index 6020ac0..d890400 100644
> > --- a/lib/utils/irqchip/fdt_irqchip_imsic.c
> > +++ b/lib/utils/irqchip/fdt_irqchip_imsic.c
> > @@ -11,16 +11,12 @@
> >  #include <libfdt.h>
> >  #include <sbi/riscv_asm.h>
> >  #include <sbi/sbi_error.h>
> > +#include <sbi/sbi_heap.h>
> >  #include <sbi/sbi_hartmask.h>
> >  #include <sbi_utils/fdt/fdt_helper.h>
> >  #include <sbi_utils/irqchip/fdt_irqchip.h>
> >  #include <sbi_utils/irqchip/imsic.h>
> >
> > -#define IMSIC_MAX_NR                 16
> > -
> > -static unsigned long imsic_count = 0;
> > -static struct imsic_data imsic[IMSIC_MAX_NR];
> > -
> >  static int irqchip_imsic_update_hartid_table(void *fdt, int nodeoff,
> >                                            struct imsic_data *id)
> >  {
> > @@ -71,25 +67,31 @@ static int irqchip_imsic_cold_init(void *fdt, int nodeoff,
> >       int rc;
> >       struct imsic_data *id;
> >
> > -     if (IMSIC_MAX_NR <= imsic_count)
> > -             return SBI_ENOSPC;
> > -     id = &imsic[imsic_count];
> > +     id = sbi_zalloc(sizeof(*id));
> > +     if (!id)
> > +             return SBI_ENOMEM;
> >
> >       rc = fdt_parse_imsic_node(fdt, nodeoff, id);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(id);
> >               return rc;
> > -     if (!id->targets_mmode)
> > +     }
> > +     if (!id->targets_mmode) {
> > +             sbi_free(id);
> >               return 0;
> > +     }
> >
> >       rc = irqchip_imsic_update_hartid_table(fdt, nodeoff, id);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(id);
> >               return rc;
> > +     }
> >
> >       rc = imsic_cold_irqchip_init(id);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(id);
> >               return rc;
> > -
> > -     imsic_count++;
> > +     }
>
> Could have a label at the bottom
>
>     return 0;
> error:
>     sbi_free(id);
>     return rc;
>
> Just need to set rc=0 before the id->targets_mmode test and everything can
> goto error rather than needing to remember to free at each point.

Okay, I will update.

>
> >
> >       return 0;
> >  }
> > diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
> > index 1aadf91..605f44a 100644
> > --- a/lib/utils/irqchip/fdt_irqchip_plic.c
> > +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
> > @@ -11,18 +11,14 @@
> >  #include <sbi/riscv_asm.h>
> >  #include <sbi/riscv_io.h>
> >  #include <sbi/sbi_error.h>
> > +#include <sbi/sbi_heap.h>
> >  #include <sbi/sbi_hartmask.h>
> >  #include <sbi_utils/fdt/fdt_helper.h>
> >  #include <sbi_utils/irqchip/fdt_irqchip.h>
> >  #include <sbi_utils/irqchip/plic.h>
> >
> > -#define PLIC_MAX_NR                  16
> > -
> > -static unsigned long plic_count = 0;
> > -static struct plic_data plic[PLIC_MAX_NR];
> > -
> >  static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
> > -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2];
> > +static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
> >
> >  void fdt_plic_priority_save(u8 *priority, u32 num)
> >  {
> > @@ -114,16 +110,18 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> >  static int irqchip_plic_cold_init(void *fdt, int nodeoff,
> >                                 const struct fdt_match *match)
> >  {
> > -     int i, rc;
> > +     int rc;
> >       struct plic_data *pd;
> >
> > -     if (PLIC_MAX_NR <= plic_count)
> > -             return SBI_ENOSPC;
> > -     pd = &plic[plic_count++];
> > +     pd = sbi_zalloc(sizeof(*pd));
> > +     if (!pd)
> > +             return SBI_ENOMEM;
> >
> >       rc = fdt_parse_plic_node(fdt, nodeoff, pd);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(pd);
> >               return rc;
> > +     }
> >
> >       if (match->data) {
> >               void (*plic_plat_init)(struct plic_data *) = match->data;
> > @@ -131,18 +129,18 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
> >       }
> >
> >       rc = plic_cold_irqchip_init(pd);
> > -     if (rc)
> > +     if (rc) {
> > +             sbi_free(pd);
> >               return rc;
> > +     }
> >
> > -     if (plic_count == 1) {
> > -             for (i = 0; i < SBI_HARTMASK_MAX_BITS; i++) {
> > -                     plic_hartid2data[i] = NULL;
> > -                     plic_hartid2context[i][0] = -1;
> > -                     plic_hartid2context[i][1] = -1;
> > -             }
> > +     rc = irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
> > +     if (rc) {
> > +             sbi_free(pd);
> > +             return rc;
> >       }
> >
> > -     return irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
> > +     return 0;
>
> Same comment as above.

Okay, I will update.

>
> >  }
> >
> >  #define THEAD_PLIC_CTRL_REG 0x1ffffc
> > --
> > 2.34.1
> >
>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>
> Thanks,
> drew

Regards,
Anup


From anup at brainfault.org  Sun Jun  4 21:00:21 2023
From: anup at brainfault.org (Anup Patel)
Date: Mon, 5 Jun 2023 09:30:21 +0530
Subject: [PATCH 12/17] lib: utils/fdt: Use heap in FDT domain parsing
In-Reply-To: <20230531-98638823b710caec91cb1374@orel>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-13-apatel@ventanamicro.com> <20230531-98638823b710caec91cb1374@orel>
Message-ID: <CAAhSdy1xfM1M6pkaWbaPfzVd929=FXKi14rPd7=Mkxo5PjujQw@mail.gmail.com>

On Wed, May 31, 2023 at 6:32?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Tue, Apr 25, 2023 at 06:02:25PM +0530, Anup Patel wrote:
> > Let's use heap allocation in FDT domain parsing instead of using
> > a fixed size global array.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  lib/utils/fdt/fdt_domain.c | 111 +++++++++++++++++++++++--------------
> >  1 file changed, 68 insertions(+), 43 deletions(-)
> >
> > diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
> > index bb6d17d..c4aed4d 100644
> > --- a/lib/utils/fdt/fdt_domain.c
> > +++ b/lib/utils/fdt/fdt_domain.c
> > @@ -13,6 +13,7 @@
> >  #include <sbi/sbi_domain.h>
> >  #include <sbi/sbi_error.h>
> >  #include <sbi/sbi_hartmask.h>
> > +#include <sbi/sbi_heap.h>
> >  #include <sbi/sbi_scratch.h>
> >  #include <sbi_utils/fdt/fdt_domain.h>
> >  #include <sbi_utils/fdt/fdt_helper.h>
> > @@ -219,14 +220,11 @@ skip_device_disable:
> >       fdt_nop_node(fdt, poffset);
> >  }
> >
> > -#define FDT_DOMAIN_MAX_COUNT         8
> > -#define FDT_DOMAIN_REGION_MAX_COUNT  16
>
> Why not keep this define since we still use 16 below when allocating
> dom->regions / max_regions?

Okay, I will keep FDT_DOMAIN_REGION_MAX_COUNT

>
> > -
> > -static u32 fdt_domains_count;
> > -static struct sbi_domain fdt_domains[FDT_DOMAIN_MAX_COUNT];
> > -static struct sbi_hartmask fdt_masks[FDT_DOMAIN_MAX_COUNT];
> > -static struct sbi_domain_memregion
> > -     fdt_regions[FDT_DOMAIN_MAX_COUNT][FDT_DOMAIN_REGION_MAX_COUNT + 1];
> > +struct parse_region_data {
> > +     struct sbi_domain *dom;
> > +     u32 region_count;
> > +     u32 max_regions;
> > +};
> >
> >  static int __fdt_parse_region(void *fdt, int domain_offset,
> >                             int region_offset, u32 region_access,
> > @@ -236,7 +234,7 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
> >       u32 val32;
> >       u64 val64;
> >       const u32 *val;
> > -     u32 *region_count = opaque;
> > +     struct parse_region_data *preg = opaque;
> >       struct sbi_domain_memregion *region;
> >
> >       /*
> > @@ -252,9 +250,9 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
> >               return SBI_EINVAL;
> >
> >       /* Find next region of the domain */
> > -     if (FDT_DOMAIN_REGION_MAX_COUNT <= *region_count)
> > -             return SBI_EINVAL;
> > -     region = &fdt_regions[fdt_domains_count][*region_count];
> > +     if (preg->max_regions <= preg->region_count)
> > +             return SBI_ENOSPC;
> > +     region = &preg->dom->regions[preg->region_count];
> >
> >       /* Read "base" DT property */
> >       val = fdt_getprop(fdt, region_offset, "base", &len);
> > @@ -278,7 +276,7 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
> >       if (fdt_get_property(fdt, region_offset, "mmio", NULL))
> >               region->flags |= SBI_DOMAIN_MEMREGION_MMIO;
> >
> > -     (*region_count)++;
> > +     preg->region_count++;
> >
> >       return 0;
> >  }
> > @@ -291,16 +289,30 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >       struct sbi_domain *dom;
> >       struct sbi_hartmask *mask;
> >       struct sbi_hartmask assign_mask;
> > +     struct parse_region_data preg;
> >       int *cold_domain_offset = opaque;
> > -     struct sbi_domain_memregion *reg, *regions;
> > -     int i, err, len, cpus_offset, cpu_offset, doffset;
> > +     struct sbi_domain_memregion *reg;
> > +     int i, err = 0, len, cpus_offset, cpu_offset, doffset;
> >
> > -     /* Sanity check on maximum domains we can handle */
> > -     if (FDT_DOMAIN_MAX_COUNT <= fdt_domains_count)
> > -             return SBI_EINVAL;
> > -     dom = &fdt_domains[fdt_domains_count];
> > -     mask = &fdt_masks[fdt_domains_count];
> > -     regions = &fdt_regions[fdt_domains_count][0];
> > +     dom = sbi_zalloc(sizeof(*dom));
> > +     if (!dom)
> > +             return SBI_ENOMEM;
> > +
> > +     dom->regions = sbi_calloc(sizeof(*dom->regions), 16 + 1);
> > +     if (!dom->regions) {
> > +             sbi_free(dom);
> > +             return SBI_ENOMEM;
> > +     }
> > +     preg.dom = dom;
> > +     preg.region_count = 0;
> > +     preg.max_regions = 16;
> > +
> > +     mask = sbi_zalloc(sizeof(*mask));
> > +     if (!mask) {
> > +             sbi_free(dom->regions);
> > +             sbi_free(dom);
> > +             return SBI_ENOMEM;
> > +     }
>
> Can add two more labels above fail_free_all to use in above two failure
> cases as well.

Sure, will do.

>
> >
> >       /* Read DT node name */
> >       strncpy(dom->name, fdt_get_name(fdt, domain_offset, NULL),
> > @@ -316,12 +328,14 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >               for (i = 0; i < len; i++) {
> >                       cpu_offset = fdt_node_offset_by_phandle(fdt,
> >                                                       fdt32_to_cpu(val[i]));
> > -                     if (cpu_offset < 0)
> > -                             return cpu_offset;
> > +                     if (cpu_offset < 0) {
> > +                             err = cpu_offset;
> > +                             goto fail_free_all;
> > +                     }
> >
> >                       err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
> >                       if (err)
> > -                             return err;
> > +                             goto fail_free_all;
> >
> >                       if (!fdt_node_is_enabled(fdt, cpu_offset))
> >                               continue;
> > @@ -331,14 +345,10 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >       }
> >
> >       /* Setup memregions from DT */
> > -     val32 = 0;
> > -     memset(regions, 0,
> > -                sizeof(*regions) * (FDT_DOMAIN_REGION_MAX_COUNT + 1));
> > -     dom->regions = regions;
> > -     err = fdt_iterate_each_memregion(fdt, domain_offset, &val32,
> > +     err = fdt_iterate_each_memregion(fdt, domain_offset, &preg,
> >                                        __fdt_parse_region);
> >       if (err)
> > -             return err;
> > +             goto fail_free_all;
> >
> >       /*
> >        * Copy over root domain memregions which don't allow
> > @@ -354,9 +364,11 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >                   (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) ||
> >                   (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
> >                       continue;
> > -             if (FDT_DOMAIN_REGION_MAX_COUNT <= val32)
> > -                     return SBI_EINVAL;
> > -             memcpy(&regions[val32++], reg, sizeof(*reg));
> > +             if (preg.max_regions <= preg.region_count) {
> > +                     err = SBI_EINVAL;
> > +                     goto fail_free_all;
> > +             }
> > +             memcpy(&dom->regions[preg.region_count++], reg, sizeof(*reg));
> >       }
> >       dom->fw_region_inited = root.fw_region_inited;
> >
> > @@ -427,8 +439,10 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >
> >       /* Find /cpus DT node */
> >       cpus_offset = fdt_path_offset(fdt, "/cpus");
> > -     if (cpus_offset < 0)
> > -             return cpus_offset;
> > +     if (cpus_offset < 0) {
> > +             err = cpus_offset;
> > +             goto fail_free_all;
> > +     }
> >
> >       /* HART to domain assignment mask based on CPU DT nodes */
> >       sbi_hartmask_clear_all(&assign_mask);
> > @@ -444,22 +458,33 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
> >                       continue;
> >
> >               val = fdt_getprop(fdt, cpu_offset, "opensbi-domain", &len);
> > -             if (!val || len < 4)
> > -                     return SBI_EINVAL;
> > +             if (!val || len < 4) {
> > +                     err = SBI_EINVAL;
> > +                     goto fail_free_all;
> > +             }
> >
> >               doffset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*val));
> > -             if (doffset < 0)
> > -                     return doffset;
> > +             if (doffset < 0) {
> > +                     err = doffset;
> > +                     goto fail_free_all;
> > +             }
> >
> >               if (doffset == domain_offset)
> >                       sbi_hartmask_set_hart(val32, &assign_mask);
> >       }
> >
> > -     /* Increment domains count */
> > -     fdt_domains_count++;
> > -
> >       /* Register the domain */
> > -     return sbi_domain_register(dom, &assign_mask);
> > +     err = sbi_domain_register(dom, &assign_mask);
> > +     if (err)
> > +             goto fail_free_all;
> > +
> > +     return 0;
> > +
> > +fail_free_all:
> > +     sbi_free(dom->regions);
> > +     sbi_free(mask);
> > +     sbi_free(dom);
> > +     return err;
> >  }
> >
> >  int fdt_domains_populate(void *fdt)
> > --
> > 2.34.1
> >
>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Regards,
Anup


From anup at brainfault.org  Sun Jun  4 22:31:07 2023
From: anup at brainfault.org (Anup Patel)
Date: Mon, 5 Jun 2023 11:01:07 +0530
Subject: [PATCH 15/17] lib: utils/irqchip: Use scratch space to save
 per-HART PLIC pointer
In-Reply-To: <20230531-50d3a3df6b5f858e99d1b10a@orel>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-16-apatel@ventanamicro.com> <20230531-50d3a3df6b5f858e99d1b10a@orel>
Message-ID: <CAAhSdy0FzSUyQ1Yptb42mPUKrN51QVFLzws4Okfa6jxCJnJbog@mail.gmail.com>

On Wed, May 31, 2023 at 6:42?PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Tue, Apr 25, 2023 at 06:02:28PM +0530, Anup Patel wrote:
> > Instead of using a global array indexed by hartid, we should use
> > scratch space to save per-HART PLIC pointer and PLIC context numbers.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  lib/utils/irqchip/fdt_irqchip_plic.c | 108 +++++++++++++++++++++------
> >  1 file changed, 86 insertions(+), 22 deletions(-)
> >
> > diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
> > index 605f44a..eb1e412 100644
> > --- a/lib/utils/irqchip/fdt_irqchip_plic.c
> > +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
> > @@ -12,54 +12,97 @@
> >  #include <sbi/riscv_io.h>
> >  #include <sbi/sbi_error.h>
> >  #include <sbi/sbi_heap.h>
> > -#include <sbi/sbi_hartmask.h>
> > +#include <sbi/sbi_scratch.h>
> >  #include <sbi_utils/fdt/fdt_helper.h>
> >  #include <sbi_utils/irqchip/fdt_irqchip.h>
> >  #include <sbi_utils/irqchip/plic.h>
> >
> > -static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
> > -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
> > +static unsigned long plic_ptr_offset;
> > +
> > +#define plic_get_hart_data_ptr(__scratch)                            \
> > +({                                                                   \
> > +     (void *)(*((ulong *)sbi_scratch_offset_ptr((__scratch),         \
> > +                                                plic_ptr_offset)));  \
> > +})
> > +
> > +#define plic_set_hart_data_ptr(__scratch, __imsic)                   \
> > +do {                                                                 \
> > +     *((ulong *)sbi_scratch_offset_ptr((__scratch), plic_ptr_offset))\
> > +                                     = (ulong)(__imsic);             \
> > +} while (0)
> > +
> > +static unsigned long plic_mcontext_offset;
> > +
> > +#define plic_get_hart_mcontext(__scratch)                            \
> > +({                                                                   \
> > +     long __ret =                                                    \
> > +     *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset));\
> > +     (__ret - 1);                                                    \
> > +})
> > +
> > +#define plic_set_hart_mcontext(__scratch, __mcontext)                        \
> > +do {                                                                 \
> > +     *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset))\
> > +                                     = (long)(__mcontext + 1);       \
> > +} while (0)
> > +
> > +static unsigned long plic_scontext_offset;
> > +
> > +#define plic_get_hart_scontext(__scratch)                            \
> > +({                                                                   \
> > +     long __ret =                                                    \
> > +     *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset));\
> > +     (__ret - 1);                                                    \
> > +})
> > +
> > +#define plic_set_hart_scontext(__scratch, __scontext)                        \
> > +do {                                                                 \
> > +     *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset))\
> > +                                     = (long)(__scontext + 1);       \
> > +} while (0)
>
> I guess the +/- 1 stuff is to ensure that the m/scontext offsets can be
> tested with zero to see if they need to be allocated. It'd be nice to
> add a comment explaining it.

This +/-1 stuff is to ensure that if [ms]context is not set then
plic_get_hart_[ms]context() will return -1. This approach
exploits the fact that per-HART scratch space is initialized
to zero.

>
> >
> >  void fdt_plic_priority_save(u8 *priority, u32 num)
> >  {
> > -     struct plic_data *plic = plic_hartid2data[current_hartid()];
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > -     plic_priority_save(plic, priority, num);
> > +     plic_priority_save(plic_get_hart_data_ptr(scratch), priority, num);
> >  }
> >
> >  void fdt_plic_priority_restore(const u8 *priority, u32 num)
> >  {
> > -     struct plic_data *plic = plic_hartid2data[current_hartid()];
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > -     plic_priority_restore(plic, priority, num);
> > +     plic_priority_restore(plic_get_hart_data_ptr(scratch), priority, num);
> >  }
> >
> >  void fdt_plic_context_save(bool smode, u32 *enable, u32 *threshold, u32 num)
> >  {
> > -     u32 hartid = current_hartid();
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > -     plic_context_save(plic_hartid2data[hartid],
> > -                       plic_hartid2context[hartid][smode],
> > +     plic_context_save(plic_get_hart_data_ptr(scratch),
> > +                       smode ? plic_get_hart_scontext(scratch) :
> > +                               plic_get_hart_mcontext(scratch),
> >                         enable, threshold, num);
> >  }
> >
> >  void fdt_plic_context_restore(bool smode, const u32 *enable, u32 threshold,
> >                             u32 num)
> >  {
> > -     u32 hartid = current_hartid();
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > -     plic_context_restore(plic_hartid2data[hartid],
> > -                          plic_hartid2context[hartid][smode],
> > +     plic_context_restore(plic_get_hart_data_ptr(scratch),
> > +                          smode ? plic_get_hart_scontext(scratch) :
> > +                                  plic_get_hart_mcontext(scratch),
> >                            enable, threshold, num);
> >  }
> >
> >  static int irqchip_plic_warm_init(void)
> >  {
> > -     u32 hartid = current_hartid();
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > -     return plic_warm_irqchip_init(plic_hartid2data[hartid],
> > -                                   plic_hartid2context[hartid][0],
> > -                                   plic_hartid2context[hartid][1]);
> > +     return plic_warm_irqchip_init(plic_get_hart_data_ptr(scratch),
> > +                                   plic_get_hart_mcontext(scratch),
> > +                                   plic_get_hart_scontext(scratch));
> >  }
> >
> >  static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> > @@ -67,6 +110,7 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> >  {
> >       const fdt32_t *val;
> >       u32 phandle, hwirq, hartid;
> > +     struct sbi_scratch *scratch;
> >       int i, err, count, cpu_offset, cpu_intc_offset;
> >
> >       val = fdt_getprop(fdt, nodeoff, "interrupts-extended", &count);
> > @@ -90,16 +134,17 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> >               if (err)
> >                       continue;
> >
> > -             if (SBI_HARTMASK_MAX_BITS <= hartid)
> > +             scratch = sbi_hartid_to_scratch(hartid);
> > +             if (!scratch)
> >                       continue;
> >
> > -             plic_hartid2data[hartid] = pd;
> > +             plic_set_hart_data_ptr(scratch, pd);
> >               switch (hwirq) {
> >               case IRQ_M_EXT:
> > -                     plic_hartid2context[hartid][0] = i / 2;
> > +                     plic_set_hart_mcontext(scratch, i / 2);
> >                       break;
> >               case IRQ_S_EXT:
> > -                     plic_hartid2context[hartid][1] = i / 2;
> > +                     plic_set_hart_scontext(scratch, i / 2);
> >                       break;
> >               }
> >       }
> > @@ -113,6 +158,24 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
> >       int rc;
> >       struct plic_data *pd;
> >
> > +     if (!plic_ptr_offset) {
> > +             plic_ptr_offset = sbi_scratch_alloc_offset(sizeof(ulong));
> > +             if (!plic_ptr_offset)
> > +                     return SBI_ENOMEM;
> > +     }
> > +
> > +     if (!plic_mcontext_offset) {
> > +             plic_mcontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> > +             if (!plic_mcontext_offset)
> > +                     return SBI_ENOMEM;
> > +     }
> > +
> > +     if (!plic_scontext_offset) {
> > +             plic_scontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> > +             if (!plic_scontext_offset)
> > +                     return SBI_ENOMEM;
> > +     }
> > +
> >       pd = sbi_zalloc(sizeof(*pd));
> >       if (!pd)
> >               return SBI_ENOMEM;
> > @@ -152,7 +215,8 @@ static void thead_plic_plat_init(struct plic_data *pd)
> >
> >  void thead_plic_restore(void)
> >  {
> > -     struct plic_data *plic = plic_hartid2data[current_hartid()];
> > +     struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> > +     struct plic_data *plic = plic_get_hart_data_ptr(scratch);
> >
> >       thead_plic_plat_init(plic);
> >  }
> > --
> > 2.34.1
> >
>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>

Regards,
Anup


From jrtc27 at jrtc27.com  Sun Jun  4 22:43:46 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Mon, 5 Jun 2023 06:43:46 +0100
Subject: [PATCH 15/17] lib: utils/irqchip: Use scratch space to save
 per-HART PLIC pointer
In-Reply-To: <20230425123230.3943447-16-apatel@ventanamicro.com>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-16-apatel@ventanamicro.com>
Message-ID: <C3911409-D000-4FC3-8302-4C4BAADACFE2@jrtc27.com>

On 25 Apr 2023, at 13:32, Anup Patel <apatel at ventanamicro.com> wrote:
> 
> Instead of using a global array indexed by hartid, we should use
> scratch space to save per-HART PLIC pointer and PLIC context numbers.
> 
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
> lib/utils/irqchip/fdt_irqchip_plic.c | 108 +++++++++++++++++++++------
> 1 file changed, 86 insertions(+), 22 deletions(-)
> 
> diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
> index 605f44a..eb1e412 100644
> --- a/lib/utils/irqchip/fdt_irqchip_plic.c
> +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
> @@ -12,54 +12,97 @@
> #include <sbi/riscv_io.h>
> #include <sbi/sbi_error.h>
> #include <sbi/sbi_heap.h>
> -#include <sbi/sbi_hartmask.h>
> +#include <sbi/sbi_scratch.h>
> #include <sbi_utils/fdt/fdt_helper.h>
> #include <sbi_utils/irqchip/fdt_irqchip.h>
> #include <sbi_utils/irqchip/plic.h>
> 
> -static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
> -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
> +static unsigned long plic_ptr_offset;
> +
> +#define plic_get_hart_data_ptr(__scratch) \
> +({ \
> + (void *)(*((ulong *)sbi_scratch_offset_ptr((__scratch), \
> +   plic_ptr_offset))); \

Why all the casting rather than just storing the pointer?

Jess

> +})
> +
> +#define plic_set_hart_data_ptr(__scratch, __imsic) \
> +do { \
> + *((ulong *)sbi_scratch_offset_ptr((__scratch), plic_ptr_offset))\
> + = (ulong)(__imsic); \
> +} while (0)
> +
> +static unsigned long plic_mcontext_offset;
> +
> +#define plic_get_hart_mcontext(__scratch) \
> +({ \
> + long __ret = \
> + *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset));\
> + (__ret - 1); \
> +})
> +
> +#define plic_set_hart_mcontext(__scratch, __mcontext) \
> +do { \
> + *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset))\
> + = (long)(__mcontext + 1); \
> +} while (0)
> +
> +static unsigned long plic_scontext_offset;
> +
> +#define plic_get_hart_scontext(__scratch) \
> +({ \
> + long __ret = \
> + *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset));\
> + (__ret - 1); \
> +})
> +
> +#define plic_set_hart_scontext(__scratch, __scontext) \
> +do { \
> + *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset))\
> + = (long)(__scontext + 1); \
> +} while (0)
> 
> void fdt_plic_priority_save(u8 *priority, u32 num)
> {
> - struct plic_data *plic = plic_hartid2data[current_hartid()];
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> 
> - plic_priority_save(plic, priority, num);
> + plic_priority_save(plic_get_hart_data_ptr(scratch), priority, num);
> }
> 
> void fdt_plic_priority_restore(const u8 *priority, u32 num)
> {
> - struct plic_data *plic = plic_hartid2data[current_hartid()];
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> 
> - plic_priority_restore(plic, priority, num);
> + plic_priority_restore(plic_get_hart_data_ptr(scratch), priority, num);
> }
> 
> void fdt_plic_context_save(bool smode, u32 *enable, u32 *threshold, u32 num)
> {
> - u32 hartid = current_hartid();
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> 
> - plic_context_save(plic_hartid2data[hartid],
> -  plic_hartid2context[hartid][smode],
> + plic_context_save(plic_get_hart_data_ptr(scratch),
> +  smode ? plic_get_hart_scontext(scratch) :
> +  plic_get_hart_mcontext(scratch),
>  enable, threshold, num);
> }
> 
> void fdt_plic_context_restore(bool smode, const u32 *enable, u32 threshold,
>      u32 num)
> {
> - u32 hartid = current_hartid();
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> 
> - plic_context_restore(plic_hartid2data[hartid],
> -     plic_hartid2context[hartid][smode],
> + plic_context_restore(plic_get_hart_data_ptr(scratch),
> +     smode ? plic_get_hart_scontext(scratch) :
> +     plic_get_hart_mcontext(scratch),
>     enable, threshold, num);
> }
> 
> static int irqchip_plic_warm_init(void)
> {
> - u32 hartid = current_hartid();
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> 
> - return plic_warm_irqchip_init(plic_hartid2data[hartid],
> -      plic_hartid2context[hartid][0],
> -      plic_hartid2context[hartid][1]);
> + return plic_warm_irqchip_init(plic_get_hart_data_ptr(scratch),
> +      plic_get_hart_mcontext(scratch),
> +      plic_get_hart_scontext(scratch));
> }
> 
> static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> @@ -67,6 +110,7 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> {
> const fdt32_t *val;
> u32 phandle, hwirq, hartid;
> + struct sbi_scratch *scratch;
> int i, err, count, cpu_offset, cpu_intc_offset;
> 
> val = fdt_getprop(fdt, nodeoff, "interrupts-extended", &count);
> @@ -90,16 +134,17 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> if (err)
> continue;
> 
> - if (SBI_HARTMASK_MAX_BITS <= hartid)
> + scratch = sbi_hartid_to_scratch(hartid);
> + if (!scratch)
> continue;
> 
> - plic_hartid2data[hartid] = pd;
> + plic_set_hart_data_ptr(scratch, pd);
> switch (hwirq) {
> case IRQ_M_EXT:
> - plic_hartid2context[hartid][0] = i / 2;
> + plic_set_hart_mcontext(scratch, i / 2);
> break;
> case IRQ_S_EXT:
> - plic_hartid2context[hartid][1] = i / 2;
> + plic_set_hart_scontext(scratch, i / 2);
> break;
> }
> }
> @@ -113,6 +158,24 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
> int rc;
> struct plic_data *pd;
> 
> + if (!plic_ptr_offset) {
> + plic_ptr_offset = sbi_scratch_alloc_offset(sizeof(ulong));
> + if (!plic_ptr_offset)
> + return SBI_ENOMEM;
> + }
> +
> + if (!plic_mcontext_offset) {
> + plic_mcontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> + if (!plic_mcontext_offset)
> + return SBI_ENOMEM;
> + }
> +
> + if (!plic_scontext_offset) {
> + plic_scontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> + if (!plic_scontext_offset)
> + return SBI_ENOMEM;
> + }
> +
> pd = sbi_zalloc(sizeof(*pd));
> if (!pd)
> return SBI_ENOMEM;
> @@ -152,7 +215,8 @@ static void thead_plic_plat_init(struct plic_data *pd)
> 
> void thead_plic_restore(void)
> {
> - struct plic_data *plic = plic_hartid2data[current_hartid()];
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> + struct plic_data *plic = plic_get_hart_data_ptr(scratch);
> 
> thead_plic_plat_init(plic);
> }
> -- 
> 2.34.1
> 
> 
> -- 
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi



From wxjstz at 126.com  Sun Jun  4 23:16:11 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:11 +0800
Subject: [PATCH 8/9] lib: sbi: Fix printi
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:04 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:04 +0800
Subject: [PATCH 1/9] lib: sbi: Fix missing contine in print
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-2-wxjstz@126.com>

Missing continue after print %lu %ld %x ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:06 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:06 +0800
Subject: [PATCH 3/9] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:05 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:05 +0800
Subject: [PATCH 2/9] lib: sbi: Fix how print gets flags
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:09 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:09 +0800
Subject: [PATCH 6/9] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:12 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:12 +0800
Subject: [PATCH 9/9] lib: sbi: Simplify prints
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-10-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:03 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:03 +0800
Subject: [PATCH 0/9] Improve sbi_console
Message-ID: <20230605061612.1030529-1-wxjstz@126.com>

Xiang W (9):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints

 lib/sbi/sbi_console.c | 243 ++++++++++++++++++++----------------------
 1 file changed, 118 insertions(+), 125 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:08 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:08 +0800
Subject: [PATCH 5/9] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:10 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:10 +0800
Subject: [PATCH 7/9] lib: sbi: print add 'o' type
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Sun Jun  4 23:16:07 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon,  5 Jun 2023 14:16:07 +0800
Subject: [PATCH 4/9] lib: sbi: Add '+' flags for print
In-Reply-To: <20230605061612.1030529-1-wxjstz@126.com>
References: <20230605061612.1030529-1-wxjstz@126.com>
Message-ID: <20230605061612.1030529-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From anup at brainfault.org  Sun Jun  4 23:51:56 2023
From: anup at brainfault.org (Anup Patel)
Date: Mon, 5 Jun 2023 12:21:56 +0530
Subject: [PATCH 15/17] lib: utils/irqchip: Use scratch space to save
 per-HART PLIC pointer
In-Reply-To: <C3911409-D000-4FC3-8302-4C4BAADACFE2@jrtc27.com>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-16-apatel@ventanamicro.com> <C3911409-D000-4FC3-8302-4C4BAADACFE2@jrtc27.com>
Message-ID: <CAAhSdy3LrndeWLUy6dELUtgTVCE+Z=zHzsJb2PxhZpG2R+S5FQ@mail.gmail.com>

On Mon, Jun 5, 2023 at 11:13?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>
> On 25 Apr 2023, at 13:32, Anup Patel <apatel at ventanamicro.com> wrote:
> >
> > Instead of using a global array indexed by hartid, we should use
> > scratch space to save per-HART PLIC pointer and PLIC context numbers.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> > lib/utils/irqchip/fdt_irqchip_plic.c | 108 +++++++++++++++++++++------
> > 1 file changed, 86 insertions(+), 22 deletions(-)
> >
> > diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
> > index 605f44a..eb1e412 100644
> > --- a/lib/utils/irqchip/fdt_irqchip_plic.c
> > +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
> > @@ -12,54 +12,97 @@
> > #include <sbi/riscv_io.h>
> > #include <sbi/sbi_error.h>
> > #include <sbi/sbi_heap.h>
> > -#include <sbi/sbi_hartmask.h>
> > +#include <sbi/sbi_scratch.h>
> > #include <sbi_utils/fdt/fdt_helper.h>
> > #include <sbi_utils/irqchip/fdt_irqchip.h>
> > #include <sbi_utils/irqchip/plic.h>
> >
> > -static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
> > -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
> > +static unsigned long plic_ptr_offset;
> > +
> > +#define plic_get_hart_data_ptr(__scratch) \
> > +({ \
> > + (void *)(*((ulong *)sbi_scratch_offset_ptr((__scratch), \
> > +   plic_ptr_offset))); \
>
> Why all the casting rather than just storing the pointer?

We are storing pointer value in scratch space as ulong but
sbi_scratch_offset_ptr() returns a void pointer to a location in
scratch space so we have to do the above casting for getting
the pointer stored in scratch space.

Thinking about this more, it is better to have generic helper
macros in sbi_scartch.h so that we don't have to define it
everywhere.

Regards,
Anup

>
> Jess
>
> > +})
> > +
> > +#define plic_set_hart_data_ptr(__scratch, __imsic) \
> > +do { \
> > + *((ulong *)sbi_scratch_offset_ptr((__scratch), plic_ptr_offset))\
> > + = (ulong)(__imsic); \
> > +} while (0)
> > +
> > +static unsigned long plic_mcontext_offset;
> > +
> > +#define plic_get_hart_mcontext(__scratch) \
> > +({ \
> > + long __ret = \
> > + *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset));\
> > + (__ret - 1); \
> > +})
> > +
> > +#define plic_set_hart_mcontext(__scratch, __mcontext) \
> > +do { \
> > + *((long *)sbi_scratch_offset_ptr((__scratch), plic_mcontext_offset))\
> > + = (long)(__mcontext + 1); \
> > +} while (0)
> > +
> > +static unsigned long plic_scontext_offset;
> > +
> > +#define plic_get_hart_scontext(__scratch) \
> > +({ \
> > + long __ret = \
> > + *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset));\
> > + (__ret - 1); \
> > +})
> > +
> > +#define plic_set_hart_scontext(__scratch, __scontext) \
> > +do { \
> > + *((long *)sbi_scratch_offset_ptr((__scratch), plic_scontext_offset))\
> > + = (long)(__scontext + 1); \
> > +} while (0)
> >
> > void fdt_plic_priority_save(u8 *priority, u32 num)
> > {
> > - struct plic_data *plic = plic_hartid2data[current_hartid()];
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > - plic_priority_save(plic, priority, num);
> > + plic_priority_save(plic_get_hart_data_ptr(scratch), priority, num);
> > }
> >
> > void fdt_plic_priority_restore(const u8 *priority, u32 num)
> > {
> > - struct plic_data *plic = plic_hartid2data[current_hartid()];
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > - plic_priority_restore(plic, priority, num);
> > + plic_priority_restore(plic_get_hart_data_ptr(scratch), priority, num);
> > }
> >
> > void fdt_plic_context_save(bool smode, u32 *enable, u32 *threshold, u32 num)
> > {
> > - u32 hartid = current_hartid();
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > - plic_context_save(plic_hartid2data[hartid],
> > -  plic_hartid2context[hartid][smode],
> > + plic_context_save(plic_get_hart_data_ptr(scratch),
> > +  smode ? plic_get_hart_scontext(scratch) :
> > +  plic_get_hart_mcontext(scratch),
> >  enable, threshold, num);
> > }
> >
> > void fdt_plic_context_restore(bool smode, const u32 *enable, u32 threshold,
> >      u32 num)
> > {
> > - u32 hartid = current_hartid();
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > - plic_context_restore(plic_hartid2data[hartid],
> > -     plic_hartid2context[hartid][smode],
> > + plic_context_restore(plic_get_hart_data_ptr(scratch),
> > +     smode ? plic_get_hart_scontext(scratch) :
> > +     plic_get_hart_mcontext(scratch),
> >     enable, threshold, num);
> > }
> >
> > static int irqchip_plic_warm_init(void)
> > {
> > - u32 hartid = current_hartid();
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> >
> > - return plic_warm_irqchip_init(plic_hartid2data[hartid],
> > -      plic_hartid2context[hartid][0],
> > -      plic_hartid2context[hartid][1]);
> > + return plic_warm_irqchip_init(plic_get_hart_data_ptr(scratch),
> > +      plic_get_hart_mcontext(scratch),
> > +      plic_get_hart_scontext(scratch));
> > }
> >
> > static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> > @@ -67,6 +110,7 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> > {
> > const fdt32_t *val;
> > u32 phandle, hwirq, hartid;
> > + struct sbi_scratch *scratch;
> > int i, err, count, cpu_offset, cpu_intc_offset;
> >
> > val = fdt_getprop(fdt, nodeoff, "interrupts-extended", &count);
> > @@ -90,16 +134,17 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
> > if (err)
> > continue;
> >
> > - if (SBI_HARTMASK_MAX_BITS <= hartid)
> > + scratch = sbi_hartid_to_scratch(hartid);
> > + if (!scratch)
> > continue;
> >
> > - plic_hartid2data[hartid] = pd;
> > + plic_set_hart_data_ptr(scratch, pd);
> > switch (hwirq) {
> > case IRQ_M_EXT:
> > - plic_hartid2context[hartid][0] = i / 2;
> > + plic_set_hart_mcontext(scratch, i / 2);
> > break;
> > case IRQ_S_EXT:
> > - plic_hartid2context[hartid][1] = i / 2;
> > + plic_set_hart_scontext(scratch, i / 2);
> > break;
> > }
> > }
> > @@ -113,6 +158,24 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
> > int rc;
> > struct plic_data *pd;
> >
> > + if (!plic_ptr_offset) {
> > + plic_ptr_offset = sbi_scratch_alloc_offset(sizeof(ulong));
> > + if (!plic_ptr_offset)
> > + return SBI_ENOMEM;
> > + }
> > +
> > + if (!plic_mcontext_offset) {
> > + plic_mcontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> > + if (!plic_mcontext_offset)
> > + return SBI_ENOMEM;
> > + }
> > +
> > + if (!plic_scontext_offset) {
> > + plic_scontext_offset = sbi_scratch_alloc_offset(sizeof(long));
> > + if (!plic_scontext_offset)
> > + return SBI_ENOMEM;
> > + }
> > +
> > pd = sbi_zalloc(sizeof(*pd));
> > if (!pd)
> > return SBI_ENOMEM;
> > @@ -152,7 +215,8 @@ static void thead_plic_plat_init(struct plic_data *pd)
> >
> > void thead_plic_restore(void)
> > {
> > - struct plic_data *plic = plic_hartid2data[current_hartid()];
> > + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> > + struct plic_data *plic = plic_get_hart_data_ptr(scratch);
> >
> > thead_plic_plat_init(plic);
> > }
> > --
> > 2.34.1
> >
> >
> > --
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi
>


From jrtc27 at jrtc27.com  Sun Jun  4 23:57:07 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Mon, 5 Jun 2023 07:57:07 +0100
Subject: [PATCH 15/17] lib: utils/irqchip: Use scratch space to save
 per-HART PLIC pointer
In-Reply-To: <CAAhSdy3LrndeWLUy6dELUtgTVCE+Z=zHzsJb2PxhZpG2R+S5FQ@mail.gmail.com>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-16-apatel@ventanamicro.com>
 <C3911409-D000-4FC3-8302-4C4BAADACFE2@jrtc27.com>
 <CAAhSdy3LrndeWLUy6dELUtgTVCE+Z=zHzsJb2PxhZpG2R+S5FQ@mail.gmail.com>
Message-ID: <59E6DFC8-989C-45F1-8A95-E723E5415FDC@jrtc27.com>

On 5 Jun 2023, at 07:51, Anup Patel <anup at brainfault.org> wrote:
> 
> On Mon, Jun 5, 2023 at 11:13?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>> 
>> On 25 Apr 2023, at 13:32, Anup Patel <apatel at ventanamicro.com> wrote:
>>> 
>>> Instead of using a global array indexed by hartid, we should use
>>> scratch space to save per-HART PLIC pointer and PLIC context numbers.
>>> 
>>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>>> ---
>>> lib/utils/irqchip/fdt_irqchip_plic.c | 108 +++++++++++++++++++++------
>>> 1 file changed, 86 insertions(+), 22 deletions(-)
>>> 
>>> diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
>>> index 605f44a..eb1e412 100644
>>> --- a/lib/utils/irqchip/fdt_irqchip_plic.c
>>> +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
>>> @@ -12,54 +12,97 @@
>>> #include <sbi/riscv_io.h>
>>> #include <sbi/sbi_error.h>
>>> #include <sbi/sbi_heap.h>
>>> -#include <sbi/sbi_hartmask.h>
>>> +#include <sbi/sbi_scratch.h>
>>> #include <sbi_utils/fdt/fdt_helper.h>
>>> #include <sbi_utils/irqchip/fdt_irqchip.h>
>>> #include <sbi_utils/irqchip/plic.h>
>>> 
>>> -static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
>>> -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
>>> +static unsigned long plic_ptr_offset;
>>> +
>>> +#define plic_get_hart_data_ptr(__scratch) \
>>> +({ \
>>> + (void *)(*((ulong *)sbi_scratch_offset_ptr((__scratch), \
>>> +   plic_ptr_offset))); \
>> 
>> Why all the casting rather than just storing the pointer?
> 
> We are storing pointer value in scratch space as ulong but
> sbi_scratch_offset_ptr() returns a void pointer to a location in
> scratch space so we have to do the above casting for getting
> the pointer stored in scratch space.
> 
> Thinking about this more, it is better to have generic helper
> macros in sbi_scartch.h so that we don't have to define it
> everywhere.

Pointers are not longs. This isn?t the Linux kernel, you don?t
need to be allergic to using the correct types for things.

Jess



From anup at brainfault.org  Mon Jun  5 04:23:17 2023
From: anup at brainfault.org (Anup Patel)
Date: Mon, 5 Jun 2023 16:53:17 +0530
Subject: [PATCH 15/17] lib: utils/irqchip: Use scratch space to save
 per-HART PLIC pointer
In-Reply-To: <59E6DFC8-989C-45F1-8A95-E723E5415FDC@jrtc27.com>
References: <20230425123230.3943447-1-apatel@ventanamicro.com>
 <20230425123230.3943447-16-apatel@ventanamicro.com> <C3911409-D000-4FC3-8302-4C4BAADACFE2@jrtc27.com>
 <CAAhSdy3LrndeWLUy6dELUtgTVCE+Z=zHzsJb2PxhZpG2R+S5FQ@mail.gmail.com> <59E6DFC8-989C-45F1-8A95-E723E5415FDC@jrtc27.com>
Message-ID: <CAAhSdy3z0S1CoTbUF5fkVZcQNf2Ddaxus29U22Tio6nOc7-sSg@mail.gmail.com>

On Mon, Jun 5, 2023 at 12:27?PM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>
> On 5 Jun 2023, at 07:51, Anup Patel <anup at brainfault.org> wrote:
> >
> > On Mon, Jun 5, 2023 at 11:13?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
> >>
> >> On 25 Apr 2023, at 13:32, Anup Patel <apatel at ventanamicro.com> wrote:
> >>>
> >>> Instead of using a global array indexed by hartid, we should use
> >>> scratch space to save per-HART PLIC pointer and PLIC context numbers.
> >>>
> >>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> >>> ---
> >>> lib/utils/irqchip/fdt_irqchip_plic.c | 108 +++++++++++++++++++++------
> >>> 1 file changed, 86 insertions(+), 22 deletions(-)
> >>>
> >>> diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
> >>> index 605f44a..eb1e412 100644
> >>> --- a/lib/utils/irqchip/fdt_irqchip_plic.c
> >>> +++ b/lib/utils/irqchip/fdt_irqchip_plic.c
> >>> @@ -12,54 +12,97 @@
> >>> #include <sbi/riscv_io.h>
> >>> #include <sbi/sbi_error.h>
> >>> #include <sbi/sbi_heap.h>
> >>> -#include <sbi/sbi_hartmask.h>
> >>> +#include <sbi/sbi_scratch.h>
> >>> #include <sbi_utils/fdt/fdt_helper.h>
> >>> #include <sbi_utils/irqchip/fdt_irqchip.h>
> >>> #include <sbi_utils/irqchip/plic.h>
> >>>
> >>> -static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
> >>> -static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
> >>> +static unsigned long plic_ptr_offset;
> >>> +
> >>> +#define plic_get_hart_data_ptr(__scratch) \
> >>> +({ \
> >>> + (void *)(*((ulong *)sbi_scratch_offset_ptr((__scratch), \
> >>> +   plic_ptr_offset))); \
> >>
> >> Why all the casting rather than just storing the pointer?
> >
> > We are storing pointer value in scratch space as ulong but
> > sbi_scratch_offset_ptr() returns a void pointer to a location in
> > scratch space so we have to do the above casting for getting
> > the pointer stored in scratch space.
> >
> > Thinking about this more, it is better to have generic helper
> > macros in sbi_scartch.h so that we don't have to define it
> > everywhere.
>
> Pointers are not longs. This isn?t the Linux kernel, you don?t
> need to be allergic to using the correct types for things.
>

Okay, I will improve this in v2.

Regards,
Anup


From apatel at ventanamicro.com  Mon Jun  5 04:37:31 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:31 +0530
Subject: [PATCH v2 00/18] Introduce and use simple heap allocator
Message-ID: <20230605113749.230696-1-apatel@ventanamicro.com>

Currently, we use global variables instead of explicitly allocating
memory in different parts of OpenSBI. This leads to a bloated BSS
section in the firmware binaries and this will continue to grow as
more drivers (and frameworks) with global variables are added.

To improve memory utilizaiton in OpenSBI:
1) We introduce a simple heap allocator which based on linked list.
   This is a reasonable heap implementation to start with because
   heap allocation and free-up won't be in hot path.
2) Use a combination of heap allocations and scratch space allocations
   to improve the reduce the BSS memory foot-print.

As a by-product, this series also redunces global arrays indexed by hartid
which is preparatory work for the upcoming full sparse hartid support.

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

Chagnes since v1:
 - Addressed Drew's comments in PATCH2, PATCH6, PATCH10, PATCH12, and
   PATCH15
 - New PATCH which adds helper macros in sbi_scratch.h to access
   data type from scratch space.

Anup Patel (18):
  include: sbi_scratch: Add helper macros to access data type
  platform: Allow platforms to specify heap size
  lib: sbi: Introduce simple heap allocator
  lib: sbi: Print scratch size and usage at boot time
  lib: sbi_pmu: Use heap for per-HART PMU state
  lib: sbi: Use heap for root domain creation
  lib: sbi: Use scratch space to save per-HART domain pointer
  lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
  lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
  lib: utils/ipi: Use heap in ACLINT MSWI driver
  lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
  lib: utils/timer: Use heap in ACLINT MTIMER driver
  lib: utils/fdt: Use heap in FDT domain parsing
  lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
  lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
  lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
  lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
  lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer

 firmware/fw_base.S                    |  15 ++
 include/sbi/sbi_domain.h              |   6 +-
 include/sbi/sbi_heap.h                |  44 ++++++
 include/sbi/sbi_platform.h            |  18 ++-
 include/sbi/sbi_scratch.h             |  48 ++++--
 lib/sbi/objects.mk                    |   1 +
 lib/sbi/sbi_domain.c                  |  84 ++++++++--
 lib/sbi/sbi_heap.c                    | 206 ++++++++++++++++++++++++
 lib/sbi/sbi_init.c                    |  20 +++
 lib/sbi/sbi_pmu.c                     | 215 +++++++++++++++-----------
 lib/sbi/sbi_scratch.c                 |  11 ++
 lib/utils/fdt/fdt_domain.c            | 113 +++++++++-----
 lib/utils/gpio/fdt_gpio_sifive.c      |  21 ++-
 lib/utils/gpio/fdt_gpio_starfive.c    |  20 +--
 lib/utils/i2c/fdt_i2c_dw.c            |  24 ++-
 lib/utils/i2c/fdt_i2c_sifive.c        |  23 ++-
 lib/utils/ipi/aclint_mswi.c           |  43 ++++--
 lib/utils/ipi/fdt_ipi_mswi.c          |  21 ++-
 lib/utils/irqchip/fdt_irqchip_aplic.c |  24 +--
 lib/utils/irqchip/fdt_irqchip_imsic.c |  35 ++---
 lib/utils/irqchip/fdt_irqchip_plic.c  | 118 +++++++++-----
 lib/utils/irqchip/imsic.c             |  76 +++++++--
 lib/utils/timer/aclint_mtimer.c       |  76 +++++++--
 lib/utils/timer/fdt_timer_mtimer.c    |  47 ++++--
 platform/fpga/ariane/platform.c       |   1 +
 platform/fpga/openpiton/platform.c    |   2 +
 platform/generic/platform.c           |   3 +-
 platform/kendryte/k210/platform.c     |   2 +
 platform/nuclei/ux600/platform.c      |   2 +
 platform/template/platform.c          |   1 +
 30 files changed, 971 insertions(+), 349 deletions(-)
 create mode 100644 include/sbi/sbi_heap.h
 create mode 100644 lib/sbi/sbi_heap.c

-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:32 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:32 +0530
Subject: [PATCH v2 01/18] include: sbi_scratch: Add helper macros to access data type
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-2-apatel@ventanamicro.com>

Reading and writing a data type in scratch space is a very common
use-case so let us add related helper macros in sbi_scratch.h.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 include/sbi/sbi_scratch.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/include/sbi/sbi_scratch.h b/include/sbi/sbi_scratch.h
index 2966188..58f2d06 100644
--- a/include/sbi/sbi_scratch.h
+++ b/include/sbi/sbi_scratch.h
@@ -174,6 +174,23 @@ void sbi_scratch_free_offset(unsigned long offset);
 #define sbi_scratch_thishart_offset_ptr(offset)	\
 	(void *)((char *)sbi_scratch_thishart_ptr() + (offset))
 
+/** Allocate offset for a data type in sbi_scratch */
+#define sbi_scratch_alloc_type_offset(__type)				\
+	sbi_scratch_alloc_offset(sizeof(__type))
+
+/** Read a data type from sbi_scratch at given offset */
+#define sbi_scratch_read_type(__scratch, __type, __offset)		\
+({									\
+	*((__type *)sbi_scratch_offset_ptr((__scratch), (__offset)));	\
+})
+
+/** Write a data type to sbi_scratch at given offset */
+#define sbi_scratch_write_type(__scratch, __type, __offset, __ptr)	\
+do {									\
+	*((__type *)sbi_scratch_offset_ptr((__scratch), (__offset)))	\
+					= (__type)(__ptr);		\
+} while (0)
+
 /** HART id to scratch table */
 extern struct sbi_scratch *hartid_to_scratch_table[];
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:33 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:33 +0530
Subject: [PATCH v2 02/18] platform: Allow platforms to specify heap size
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-3-apatel@ventanamicro.com>

We extend struct sbi_platform and struct sbi_scratch to allow platforms
specify the heap size to the OpenSBI firmwares. The OpenSBI firmwares
will use this information to determine the location of heap and provide
heap base address in per-HART scratch space.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 firmware/fw_base.S                 | 15 +++++++++++++++
 include/sbi/sbi_platform.h         | 18 +++++++++++++++---
 include/sbi/sbi_scratch.h          | 28 ++++++++++++++++++----------
 platform/fpga/ariane/platform.c    |  1 +
 platform/fpga/openpiton/platform.c |  2 ++
 platform/generic/platform.c        |  3 ++-
 platform/kendryte/k210/platform.c  |  2 ++
 platform/nuclei/ux600/platform.c   |  2 ++
 platform/template/platform.c       |  1 +
 9 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index e37df09..fff09e1 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -255,20 +255,28 @@ _bss_zero:
 	/* Preload HART details
 	 * s7 -> HART Count
 	 * s8 -> HART Stack Size
+	 * s9 -> Heap Size
+	 * s10 -> Heap Offset
 	 */
 	lla	a4, platform
 #if __riscv_xlen > 32
 	lwu	s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
 	lwu	s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
+	lwu	s9, SBI_PLATFORM_HEAP_SIZE_OFFSET(a4)
 #else
 	lw	s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
 	lw	s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
+	lw	s9, SBI_PLATFORM_HEAP_SIZE_OFFSET(a4)
 #endif
 
 	/* Setup scratch space for all the HARTs*/
 	lla	tp, _fw_end
 	mul	a5, s7, s8
 	add	tp, tp, a5
+	/* Setup heap base address */
+	lla	s10, _fw_start
+	sub	s10, tp, s10
+	add	tp, tp, s9
 	/* Keep a copy of tp */
 	add	t3, tp, zero
 	/* Counter */
@@ -283,8 +291,11 @@ _scratch_init:
 	 * t3 -> the firmware end address
 	 * s7 -> HART count
 	 * s8 -> HART stack size
+	 * s9 -> Heap Size
+	 * s10 -> Heap Offset
 	 */
 	add	tp, t3, zero
+	sub	tp, tp, s9
 	mul	a5, s8, t1
 	sub	tp, tp, a5
 	li	a5, SBI_SCRATCH_SIZE
@@ -302,6 +313,10 @@ _scratch_init:
 	REG_L	a5, 0(a4)
 	REG_S	a5, SBI_SCRATCH_FW_RW_OFFSET(tp)
 
+	/* Store fw_heap_offset and fw_heap_size in scratch space */
+	REG_S	s10, SBI_SCRATCH_FW_HEAP_OFFSET(tp)
+	REG_S	s9, SBI_SCRATCH_FW_HEAP_SIZE_OFFSET(tp)
+
 	/* Store next arg1 in scratch space */
 	MOV_3R	s0, a0, s1, a1, s2, a2
 	call	fw_next_arg1
diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index 546c0a6..3e9616f 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -29,12 +29,16 @@
 #define SBI_PLATFORM_HART_COUNT_OFFSET (0x50)
 /** Offset of hart_stack_size in struct sbi_platform */
 #define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x54)
+/** Offset of heap_size in struct sbi_platform */
+#define SBI_PLATFORM_HEAP_SIZE_OFFSET (0x58)
+/** Offset of reserved in struct sbi_platform */
+#define SBI_PLATFORM_RESERVED_OFFSET (0x5c)
 /** Offset of platform_ops_addr in struct sbi_platform */
-#define SBI_PLATFORM_OPS_OFFSET (0x58)
+#define SBI_PLATFORM_OPS_OFFSET (0x60)
 /** Offset of firmware_context in struct sbi_platform */
-#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x58 + __SIZEOF_POINTER__)
+#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x60 + __SIZEOF_POINTER__)
 /** Offset of hart_index2id in struct sbi_platform */
-#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x58 + (__SIZEOF_POINTER__ * 2))
+#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x60 + (__SIZEOF_POINTER__ * 2))
 
 #define SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT		(1UL << 12)
 
@@ -138,6 +142,10 @@ struct sbi_platform_operations {
 /** Platform default per-HART stack size for exception/interrupt handling */
 #define SBI_PLATFORM_DEFAULT_HART_STACK_SIZE	8192
 
+/** Platform default heap size */
+#define SBI_PLATFORM_DEFAULT_HEAP_SIZE(__num_hart)	\
+					(0x8000 + 0x800 * (__num_hart))
+
 /** Representation of a platform */
 struct sbi_platform {
 	/**
@@ -160,6 +168,10 @@ struct sbi_platform {
 	u32 hart_count;
 	/** Per-HART stack size for exception/interrupt handling */
 	u32 hart_stack_size;
+	/** Size of heap shared by all HARTs */
+	u32 heap_size;
+	/** Reserved for future use */
+	u32 reserved;
 	/** Pointer to sbi platform operations */
 	unsigned long platform_ops_addr;
 	/** Pointer to system firmware specific context */
diff --git a/include/sbi/sbi_scratch.h b/include/sbi/sbi_scratch.h
index 58f2d06..9894c70 100644
--- a/include/sbi/sbi_scratch.h
+++ b/include/sbi/sbi_scratch.h
@@ -20,26 +20,30 @@
 #define SBI_SCRATCH_FW_SIZE_OFFSET		(1 * __SIZEOF_POINTER__)
 /** Offset (in sbi_scratch) of the R/W Offset */
 #define SBI_SCRATCH_FW_RW_OFFSET		(2 * __SIZEOF_POINTER__)
+/** Offset of fw_heap_offset member in sbi_scratch */
+#define SBI_SCRATCH_FW_HEAP_OFFSET		(3 * __SIZEOF_POINTER__)
+/** Offset of fw_heap_size_offset member in sbi_scratch */
+#define SBI_SCRATCH_FW_HEAP_SIZE_OFFSET		(4 * __SIZEOF_POINTER__)
 /** Offset of next_arg1 member in sbi_scratch */
-#define SBI_SCRATCH_NEXT_ARG1_OFFSET		(3 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_NEXT_ARG1_OFFSET		(5 * __SIZEOF_POINTER__)
 /** Offset of next_addr member in sbi_scratch */
-#define SBI_SCRATCH_NEXT_ADDR_OFFSET		(4 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_NEXT_ADDR_OFFSET		(6 * __SIZEOF_POINTER__)
 /** Offset of next_mode member in sbi_scratch */
-#define SBI_SCRATCH_NEXT_MODE_OFFSET		(5 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_NEXT_MODE_OFFSET		(7 * __SIZEOF_POINTER__)
 /** Offset of warmboot_addr member in sbi_scratch */
-#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET	(6 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET	(8 * __SIZEOF_POINTER__)
 /** Offset of platform_addr member in sbi_scratch */
-#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET	(7 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET	(9 * __SIZEOF_POINTER__)
 /** Offset of hartid_to_scratch member in sbi_scratch */
-#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET	(8 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET	(10 * __SIZEOF_POINTER__)
 /** Offset of trap_exit member in sbi_scratch */
-#define SBI_SCRATCH_TRAP_EXIT_OFFSET		(9 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_TRAP_EXIT_OFFSET		(11 * __SIZEOF_POINTER__)
 /** Offset of tmp0 member in sbi_scratch */
-#define SBI_SCRATCH_TMP0_OFFSET			(10 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_TMP0_OFFSET			(12 * __SIZEOF_POINTER__)
 /** Offset of options member in sbi_scratch */
-#define SBI_SCRATCH_OPTIONS_OFFSET		(11 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_OPTIONS_OFFSET		(13 * __SIZEOF_POINTER__)
 /** Offset of extra space in sbi_scratch */
-#define SBI_SCRATCH_EXTRA_SPACE_OFFSET		(12 * __SIZEOF_POINTER__)
+#define SBI_SCRATCH_EXTRA_SPACE_OFFSET		(14 * __SIZEOF_POINTER__)
 /** Maximum size of sbi_scratch (4KB) */
 #define SBI_SCRATCH_SIZE			(0x1000)
 
@@ -57,6 +61,10 @@ struct sbi_scratch {
 	unsigned long fw_size;
 	/** Offset (in bytes) of the R/W section */
 	unsigned long fw_rw_offset;
+	/** Offset (in bytes) of the heap area */
+	unsigned long fw_heap_offset;
+	/** Size (in bytes) of the heap area */
+	unsigned long fw_heap_size;
 	/** Arg1 (or 'a1' register) of next booting stage for this HART */
 	unsigned long next_arg1;
 	/** Address of next booting stage for this HART */
diff --git a/platform/fpga/ariane/platform.c b/platform/fpga/ariane/platform.c
index 1e341c2..975528f 100644
--- a/platform/fpga/ariane/platform.c
+++ b/platform/fpga/ariane/platform.c
@@ -185,5 +185,6 @@ const struct sbi_platform platform = {
 	.features = SBI_PLATFORM_DEFAULT_FEATURES,
 	.hart_count = ARIANE_HART_COUNT,
 	.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size = SBI_PLATFORM_DEFAULT_HEAP_SIZE(ARIANE_HART_COUNT),
 	.platform_ops_addr = (unsigned long)&platform_ops
 };
diff --git a/platform/fpga/openpiton/platform.c b/platform/fpga/openpiton/platform.c
index 57ae698..e59dc99 100644
--- a/platform/fpga/openpiton/platform.c
+++ b/platform/fpga/openpiton/platform.c
@@ -220,5 +220,7 @@ const struct sbi_platform platform = {
 	.features = SBI_PLATFORM_DEFAULT_FEATURES,
 	.hart_count = OPENPITON_DEFAULT_HART_COUNT,
 	.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size =
+		SBI_PLATFORM_DEFAULT_HEAP_SIZE(OPENPITON_DEFAULT_HART_COUNT),
 	.platform_ops_addr = (unsigned long)&platform_ops
 };
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index eeefef4..0c9cd95 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -115,7 +115,7 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
 	}
 
 	platform.hart_count = hart_count;
-
+	platform.heap_size = SBI_PLATFORM_DEFAULT_HEAP_SIZE(hart_count);
 	platform_has_mlevel_imsic = fdt_check_imsic_mlevel(fdt);
 
 	/* Return original FDT pointer */
@@ -315,5 +315,6 @@ struct sbi_platform platform = {
 	.hart_count		= SBI_HARTMASK_MAX_BITS,
 	.hart_index2id		= generic_hart_index2id,
 	.hart_stack_size	= SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size		= SBI_PLATFORM_DEFAULT_HEAP_SIZE(0),
 	.platform_ops_addr	= (unsigned long)&platform_ops
 };
diff --git a/platform/kendryte/k210/platform.c b/platform/kendryte/k210/platform.c
index 7eb9015..637a217 100644
--- a/platform/kendryte/k210/platform.c
+++ b/platform/kendryte/k210/platform.c
@@ -196,5 +196,7 @@ const struct sbi_platform platform = {
 	.features		= 0,
 	.hart_count		= K210_HART_COUNT,
 	.hart_stack_size	= SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size		=
+			SBI_PLATFORM_DEFAULT_HEAP_SIZE(K210_HART_COUNT),
 	.platform_ops_addr	= (unsigned long)&platform_ops
 };
diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c
index 4eccff1..6fd6cd7 100644
--- a/platform/nuclei/ux600/platform.c
+++ b/platform/nuclei/ux600/platform.c
@@ -244,5 +244,7 @@ const struct sbi_platform platform = {
 	.features		= SBI_PLATFORM_DEFAULT_FEATURES,
 	.hart_count		= UX600_HART_COUNT,
 	.hart_stack_size	= SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size		=
+			SBI_PLATFORM_DEFAULT_HEAP_SIZE(UX600_HART_COUNT),
 	.platform_ops_addr	= (unsigned long)&platform_ops
 };
diff --git a/platform/template/platform.c b/platform/template/platform.c
index 8adc431..86381ca 100644
--- a/platform/template/platform.c
+++ b/platform/template/platform.c
@@ -152,5 +152,6 @@ const struct sbi_platform platform = {
 	.features		= SBI_PLATFORM_DEFAULT_FEATURES,
 	.hart_count		= 1,
 	.hart_stack_size	= SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+	.heap_size		= SBI_PLATFORM_DEFAULT_HEAP_SIZE(1),
 	.platform_ops_addr	= (unsigned long)&platform_ops
 };
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:34 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:34 +0530
Subject: [PATCH v2 03/18] lib: sbi: Introduce simple heap allocator
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-4-apatel@ventanamicro.com>

We provide simple heap allocator to manage the heap space provided
by OpenSBI firmware and platform.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/sbi/sbi_heap.h |  44 +++++++++
 lib/sbi/objects.mk     |   1 +
 lib/sbi/sbi_heap.c     | 206 +++++++++++++++++++++++++++++++++++++++++
 lib/sbi/sbi_init.c     |  15 +++
 4 files changed, 266 insertions(+)
 create mode 100644 include/sbi/sbi_heap.h
 create mode 100644 lib/sbi/sbi_heap.c

diff --git a/include/sbi/sbi_heap.h b/include/sbi/sbi_heap.h
new file mode 100644
index 0000000..88d176e
--- /dev/null
+++ b/include/sbi/sbi_heap.h
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *   Anup Patel<apatel at ventanamicro.com>
+ */
+
+#ifndef __SBI_HEAP_H__
+#define __SBI_HEAP_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_scratch;
+
+/** Allocate from heap area */
+void *sbi_malloc(size_t size);
+
+/** Zero allocate from heap area */
+void *sbi_zalloc(size_t size);
+
+/** Allocate array from heap area */
+static inline void *sbi_calloc(size_t nitems, size_t size)
+{
+	return sbi_zalloc(nitems * size);
+}
+
+/** Free-up to heap area */
+void sbi_free(void *ptr);
+
+/** Amount (in bytes) of free space in the heap area */
+unsigned long sbi_heap_free_space(void);
+
+/** Amount (in bytes) of used space in the heap area */
+unsigned long sbi_heap_used_space(void);
+
+/** Amount (in bytes) of reserved space in the heap area */
+unsigned long sbi_heap_reserved_space(void);
+
+/** Initialize heap area */
+int sbi_heap_init(struct sbi_scratch *scratch);
+
+#endif
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index 7d691c6..c699187 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -59,6 +59,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
 libsbi-objs-y += sbi_hsm.o
diff --git a/lib/sbi/sbi_heap.c b/lib/sbi/sbi_heap.c
new file mode 100644
index 0000000..698c377
--- /dev/null
+++ b/lib/sbi/sbi_heap.c
@@ -0,0 +1,206 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Authors:
+ *   Anup Patel<apatel at ventanamicro.com>
+ */
+
+#include <sbi/riscv_locks.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_list.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_string.h>
+
+/* Alignment of heap base address and size */
+#define HEAP_BASE_ALIGN			1024
+/* Minimum size and alignment of heap allocations */
+#define HEAP_ALLOC_ALIGN		64
+#define HEAP_HOUSEKEEPING_FACTOR	16
+
+struct heap_node {
+	struct sbi_dlist head;
+	unsigned long addr;
+	unsigned long size;
+};
+
+struct heap_control {
+	spinlock_t lock;
+	unsigned long base;
+	unsigned long size;
+	unsigned long hkbase;
+	unsigned long hksize;
+	struct sbi_dlist free_node_list;
+	struct sbi_dlist free_space_list;
+	struct sbi_dlist used_space_list;
+};
+
+static struct heap_control hpctrl;
+
+void *sbi_malloc(size_t size)
+{
+	void *ret = NULL;
+	struct heap_node *n, *np;
+
+	if (!size)
+		return NULL;
+
+	size += HEAP_ALLOC_ALIGN - 1;
+	size &= ~((unsigned long)HEAP_ALLOC_ALIGN - 1);
+
+	spin_lock(&hpctrl.lock);
+
+	np = NULL;
+	sbi_list_for_each_entry(n, &hpctrl.free_space_list, head) {
+		if (size <= n->size) {
+			np = n;
+			break;
+		}
+	}
+	if (np) {
+		if ((size < np->size) &&
+		    !sbi_list_empty(&hpctrl.free_node_list)) {
+			n = sbi_list_first_entry(&hpctrl.free_node_list,
+						 struct heap_node, head);
+			sbi_list_del(&n->head);
+			n->addr = np->addr + np->size - size;
+			n->size = size;
+			np->size -= size;
+			sbi_list_add_tail(&n->head, &hpctrl.used_space_list);
+			ret = (void *)n->addr;
+		} else if (size == np->size) {
+			sbi_list_del(&np->head);
+			sbi_list_add_tail(&np->head, &hpctrl.used_space_list);
+			ret = (void *)np->addr;
+		}
+	}
+
+	spin_unlock(&hpctrl.lock);
+
+	return ret;
+}
+
+void *sbi_zalloc(size_t size)
+{
+	void *ret = sbi_malloc(size);
+
+	if (ret)
+		sbi_memset(ret, 0, size);
+	return ret;
+}
+
+void sbi_free(void *ptr)
+{
+	struct heap_node *n, *np;
+
+	if (!ptr)
+		return;
+
+	spin_lock(&hpctrl.lock);
+
+	np = NULL;
+	sbi_list_for_each_entry(n, &hpctrl.used_space_list, head) {
+		if ((n->addr <= (unsigned long)ptr) &&
+		    ((unsigned long)ptr < (n->addr + n->size))) {
+			np = n;
+			break;
+		}
+	}
+	if (!np) {
+		spin_unlock(&hpctrl.lock);
+		return;
+	}
+
+	sbi_list_del(&np->head);
+
+	sbi_list_for_each_entry(n, &hpctrl.free_space_list, head) {
+		if ((np->addr + np->size) == n->addr) {
+			n->addr = np->addr;
+			n->size += np->size;
+			sbi_list_add_tail(&np->head, &hpctrl.free_node_list);
+			np = NULL;
+			break;
+		} else if (np->addr == (n->addr + n->size)) {
+			n->size += np->size;
+			sbi_list_add_tail(&np->head, &hpctrl.free_node_list);
+			np = NULL;
+			break;
+		} else if ((n->addr + n->size) < np->addr) {
+			sbi_list_add(&np->head, &n->head);
+			np = NULL;
+			break;
+		}
+	}
+	if (np)
+		sbi_list_add_tail(&np->head, &hpctrl.free_space_list);
+
+	spin_unlock(&hpctrl.lock);
+}
+
+unsigned long sbi_heap_free_space(void)
+{
+	struct heap_node *n;
+	unsigned long ret = 0;
+
+	spin_lock(&hpctrl.lock);
+	sbi_list_for_each_entry(n, &hpctrl.free_space_list, head)
+		ret += n->size;
+	spin_unlock(&hpctrl.lock);
+
+	return ret;
+}
+
+unsigned long sbi_heap_used_space(void)
+{
+	return hpctrl.size - hpctrl.hksize - sbi_heap_free_space();
+}
+
+unsigned long sbi_heap_reserved_space(void)
+{
+	return hpctrl.hksize;
+}
+
+int sbi_heap_init(struct sbi_scratch *scratch)
+{
+	unsigned long i;
+	struct heap_node *n;
+
+	/* Sanity checks on heap offset and size */
+	if (!scratch->fw_heap_size ||
+	    (scratch->fw_heap_size & (HEAP_BASE_ALIGN - 1)) ||
+	    (scratch->fw_heap_offset < scratch->fw_rw_offset) ||
+	    (scratch->fw_size < (scratch->fw_heap_offset + scratch->fw_heap_size)) ||
+	    (scratch->fw_heap_offset & (HEAP_BASE_ALIGN - 1)))
+		return SBI_EINVAL;
+
+	/* Initialize heap control */
+	SPIN_LOCK_INIT(hpctrl.lock);
+	hpctrl.base = scratch->fw_start + scratch->fw_heap_offset;
+	hpctrl.size = scratch->fw_heap_size;
+	hpctrl.hkbase = hpctrl.base;
+	hpctrl.hksize = hpctrl.size / HEAP_HOUSEKEEPING_FACTOR;
+	hpctrl.hksize &= ~((unsigned long)HEAP_BASE_ALIGN - 1);
+	SBI_INIT_LIST_HEAD(&hpctrl.free_node_list);
+	SBI_INIT_LIST_HEAD(&hpctrl.free_space_list);
+	SBI_INIT_LIST_HEAD(&hpctrl.used_space_list);
+
+	/* Prepare free node list */
+	for (i = 0; i < (hpctrl.hksize / sizeof(*n)); i++) {
+		n = (struct heap_node *)(hpctrl.hkbase + (sizeof(*n) * i));
+		SBI_INIT_LIST_HEAD(&n->head);
+		n->addr = n->size = 0;
+		sbi_list_add_tail(&n->head, &hpctrl.free_node_list);
+	}
+
+	/* Prepare free space list */
+	n = sbi_list_first_entry(&hpctrl.free_node_list,
+				 struct heap_node, head);
+	sbi_list_del(&n->head);
+	n->addr = hpctrl.hkbase + hpctrl.hksize;
+	n->size = hpctrl.size - hpctrl.hksize;
+	sbi_list_add_tail(&n->head, &hpctrl.free_space_list);
+
+	return 0;
+}
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 7c78d9b..a170525 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -17,6 +17,7 @@
 #include <sbi/sbi_ecall.h>
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hsm.h>
 #include <sbi/sbi_ipi.h>
 #include <sbi/sbi_irqchip.h>
@@ -118,6 +119,15 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
 	sbi_printf("Firmware Size             : %d KB\n",
 		   (u32)(scratch->fw_size / 1024));
 	sbi_printf("Firmware RW Offset        : 0x%lx\n", scratch->fw_rw_offset);
+	sbi_printf("Firmware RW Size          : %d KB\n",
+		   (u32)((scratch->fw_size - scratch->fw_rw_offset) / 1024));
+	sbi_printf("Firmware Heap Offset      : 0x%lx\n", scratch->fw_heap_offset);
+	sbi_printf("Firmware Heap Size        : "
+		   "%d KB (total), %d KB (reserved), %d KB (used), %d KB (free)\n",
+		   (u32)(scratch->fw_heap_size / 1024),
+		   (u32)(sbi_heap_reserved_space() / 1024),
+		   (u32)(sbi_heap_used_space() / 1024),
+		   (u32)(sbi_heap_free_space() / 1024));
 
 	/* SBI details */
 	sbi_printf("Runtime SBI Version       : %d.%d\n",
@@ -258,6 +268,11 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 		sbi_hart_hang();
 
 	/* Note: This has to be second thing in coldboot init sequence */
+	rc = sbi_heap_init(scratch);
+	if (rc)
+		sbi_hart_hang();
+
+	/* Note: This has to be the third thing in coldboot init sequence */
 	rc = sbi_domain_init(scratch, hartid);
 	if (rc)
 		sbi_hart_hang();
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:35 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:35 +0530
Subject: [PATCH v2 04/18] lib: sbi: Print scratch size and usage at boot time
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-5-apatel@ventanamicro.com>

The scratch space being a scarce resource so let us print it's
size and usage at boot time.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/sbi/sbi_scratch.h |  3 +++
 lib/sbi/sbi_init.c        |  5 +++++
 lib/sbi/sbi_scratch.c     | 11 +++++++++++
 3 files changed, 19 insertions(+)

diff --git a/include/sbi/sbi_scratch.h b/include/sbi/sbi_scratch.h
index 9894c70..4801492 100644
--- a/include/sbi/sbi_scratch.h
+++ b/include/sbi/sbi_scratch.h
@@ -175,6 +175,9 @@ unsigned long sbi_scratch_alloc_offset(unsigned long size);
 /** Free-up extra space in sbi_scratch */
 void sbi_scratch_free_offset(unsigned long offset);
 
+/** Amount (in bytes) of used space in in sbi_scratch */
+unsigned long sbi_scratch_used_space(void);
+
 /** Get pointer from offset in sbi_scratch */
 #define sbi_scratch_offset_ptr(scratch, offset)	(void *)((char *)(scratch) + (offset))
 
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index a170525..423e6d8 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -128,6 +128,11 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
 		   (u32)(sbi_heap_reserved_space() / 1024),
 		   (u32)(sbi_heap_used_space() / 1024),
 		   (u32)(sbi_heap_free_space() / 1024));
+	sbi_printf("Firmware Scratch Size     : "
+		   "%d B (total), %d B (used), %d B (free)\n",
+		   SBI_SCRATCH_SIZE,
+		   (u32)sbi_scratch_used_space(),
+		   (u32)(SBI_SCRATCH_SIZE - sbi_scratch_used_space()));
 
 	/* SBI details */
 	sbi_printf("Runtime SBI Version       : %d.%d\n",
diff --git a/lib/sbi/sbi_scratch.c b/lib/sbi/sbi_scratch.c
index 55ebdbb..87ef84c 100644
--- a/lib/sbi/sbi_scratch.c
+++ b/lib/sbi/sbi_scratch.c
@@ -97,3 +97,14 @@ void sbi_scratch_free_offset(unsigned long offset)
 	 * brain-dead allocator.
 	 */
 }
+
+unsigned long sbi_scratch_used_space(void)
+{
+	unsigned long ret = 0;
+
+	spin_lock(&extra_lock);
+	ret = extra_offset;
+	spin_unlock(&extra_lock);
+
+	return ret;
+}
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:36 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:36 +0530
Subject: [PATCH v2 05/18] lib: sbi_pmu: Use heap for per-HART PMU state
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-6-apatel@ventanamicro.com>

Instead of using a global array for per-HART PMU state, we should
use heap to on-demand allocate per-HART PMU state when the HART
is initialized in cold boot or warm boot path.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/sbi/sbi_pmu.c | 215 +++++++++++++++++++++++++++-------------------
 1 file changed, 127 insertions(+), 88 deletions(-)

diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index 939f29d..c73e6ef 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -12,7 +12,7 @@
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_ecall_interface.h>
 #include <sbi/sbi_hart.h>
-#include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_pmu.h>
 #include <sbi/sbi_scratch.h>
@@ -50,27 +50,43 @@ union sbi_pmu_ctr_info {
 	};
 };
 
-/* Platform specific PMU device */
-static const struct sbi_pmu_device *pmu_dev = NULL;
-
-/* Mapping between event range and possible counters  */
-static struct sbi_pmu_hw_event hw_event_map[SBI_PMU_HW_EVENT_MAX] = {0};
-
-/* counter to enabled event mapping */
-static uint32_t active_events[SBI_HARTMASK_MAX_BITS][SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX];
-
-/* Bitmap of firmware counters started on each HART */
 #if SBI_PMU_FW_CTR_MAX >= BITS_PER_LONG
 #error "Can't handle firmware counters beyond BITS_PER_LONG"
 #endif
-static unsigned long fw_counters_started[SBI_HARTMASK_MAX_BITS];
 
-/*
- * Counter values for SBI firmware events and event codes for platform
- * firmware events. Both are mutually exclusive and hence can optimally share
- * the same memory.
- */
-static uint64_t fw_counters_data[SBI_HARTMASK_MAX_BITS][SBI_PMU_FW_CTR_MAX] = {0};
+/** Per-HART state of the PMU counters */
+struct sbi_pmu_hart_state {
+	/* HART to which this state belongs */
+	uint32_t hartid;
+	/* Counter to enabled event mapping */
+	uint32_t active_events[SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX];
+	/* Bitmap of firmware counters started */
+	unsigned long fw_counters_started;
+	/*
+	 * Counter values for SBI firmware events and event codes
+	 * for platform firmware events. Both are mutually exclusive
+	 * and hence can optimally share the same memory.
+	 */
+	uint64_t fw_counters_data[SBI_PMU_FW_CTR_MAX];
+};
+
+/** Offset of pointer to PMU HART state in scratch space */
+static unsigned long phs_ptr_offset;
+
+#define pmu_get_hart_state_ptr(__scratch)				\
+	sbi_scratch_read_type((__scratch), void *, phs_ptr_offset)
+
+#define pmu_thishart_state_ptr()					\
+	pmu_get_hart_state_ptr(sbi_scratch_thishart_ptr())
+
+#define pmu_set_hart_state_ptr(__scratch, __phs)			\
+	sbi_scratch_write_type((__scratch), void *, phs_ptr_offset, (__phs))
+
+/* Platform specific PMU device */
+static const struct sbi_pmu_device *pmu_dev = NULL;
+
+/* Mapping between event range and possible counters  */
+static struct sbi_pmu_hw_event *hw_event_map;
 
 /* Maximum number of hardware events available */
 static uint32_t num_hw_events;
@@ -111,13 +127,13 @@ static bool pmu_event_select_overlap(struct sbi_pmu_hw_event *evt,
 	return false;
 }
 
-static int pmu_event_validate(unsigned long event_idx, uint64_t edata)
+static int pmu_event_validate(struct sbi_pmu_hart_state *phs,
+			      unsigned long event_idx, uint64_t edata)
 {
 	uint32_t event_idx_type = get_cidx_type(event_idx);
 	uint32_t event_idx_code = get_cidx_code(event_idx);
 	uint32_t event_idx_code_max = -1;
 	uint32_t cache_ops_result, cache_ops_id, cache_id;
-	u32 hartid = current_hartid();
 
 	switch(event_idx_type) {
 	case SBI_PMU_EVENT_TYPE_HW:
@@ -131,7 +147,7 @@ static int pmu_event_validate(unsigned long event_idx, uint64_t edata)
 
 		if (SBI_PMU_FW_PLATFORM == event_idx_code &&
 		    pmu_dev && pmu_dev->fw_event_validate_encoding)
-			return pmu_dev->fw_event_validate_encoding(hartid,
+			return pmu_dev->fw_event_validate_encoding(phs->hartid,
 							           edata);
 		else
 			event_idx_code_max = SBI_PMU_FW_MAX;
@@ -165,16 +181,16 @@ static int pmu_event_validate(unsigned long event_idx, uint64_t edata)
 	return SBI_EINVAL;
 }
 
-static int pmu_ctr_validate(uint32_t cidx, uint32_t *event_idx_code)
+static int pmu_ctr_validate(struct sbi_pmu_hart_state *phs,
+			    uint32_t cidx, uint32_t *event_idx_code)
 {
 	uint32_t event_idx_val;
 	uint32_t event_idx_type;
-	u32 hartid = current_hartid();
 
 	if (cidx >= total_ctrs)
 		return SBI_EINVAL;
 
-	event_idx_val = active_events[hartid][cidx];
+	event_idx_val = phs->active_events[cidx];
 	event_idx_type = get_cidx_type(event_idx_val);
 	if (event_idx_val == SBI_PMU_EVENT_IDX_INVALID ||
 	    event_idx_type >= SBI_PMU_EVENT_TYPE_MAX)
@@ -189,9 +205,9 @@ int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval)
 {
 	int event_idx_type;
 	uint32_t event_code;
-	u32 hartid = current_hartid();
+	struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
 
-	event_idx_type = pmu_ctr_validate(cidx, &event_code);
+	event_idx_type = pmu_ctr_validate(phs, cidx, &event_code);
 	if (event_idx_type != SBI_PMU_EVENT_TYPE_FW)
 		return SBI_EINVAL;
 
@@ -202,13 +218,13 @@ int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval)
 
 	if (SBI_PMU_FW_PLATFORM == event_code) {
 		if (pmu_dev && pmu_dev->fw_counter_read_value)
-			*cval = pmu_dev->fw_counter_read_value(hartid,
+			*cval = pmu_dev->fw_counter_read_value(phs->hartid,
 							       cidx -
 							       num_hw_ctrs);
 		else
 			*cval = 0;
 	} else
-		*cval = fw_counters_data[hartid][cidx - num_hw_ctrs];
+		*cval = phs->fw_counters_data[cidx - num_hw_ctrs];
 
 	return 0;
 }
@@ -376,12 +392,11 @@ int sbi_pmu_irq_bit(void)
 	return 0;
 }
 
-static int pmu_ctr_start_fw(uint32_t cidx, uint32_t event_code,
+static int pmu_ctr_start_fw(struct sbi_pmu_hart_state *phs,
+			    uint32_t cidx, uint32_t event_code,
 			    uint64_t event_data, uint64_t ival,
 			    bool ival_update)
 {
-	u32 hartid = current_hartid();
-
 	if ((event_code >= SBI_PMU_FW_MAX &&
 	    event_code <= SBI_PMU_FW_RESERVED_MAX) ||
 	    event_code > SBI_PMU_FW_PLATFORM)
@@ -395,18 +410,19 @@ static int pmu_ctr_start_fw(uint32_t cidx, uint32_t event_code,
 		    }
 
 		if (ival_update)
-			pmu_dev->fw_counter_write_value(hartid,
+			pmu_dev->fw_counter_write_value(phs->hartid,
 							cidx - num_hw_ctrs,
 							ival);
 
-		return pmu_dev->fw_counter_start(hartid, cidx - num_hw_ctrs,
+		return pmu_dev->fw_counter_start(phs->hartid,
+						 cidx - num_hw_ctrs,
 						 event_data);
 	} else {
 		if (ival_update)
-			fw_counters_data[hartid][cidx - num_hw_ctrs] = ival;
+			phs->fw_counters_data[cidx - num_hw_ctrs] = ival;
 	}
 
-	fw_counters_started[hartid] |= BIT(cidx - num_hw_ctrs);
+	phs->fw_counters_started |= BIT(cidx - num_hw_ctrs);
 
 	return 0;
 }
@@ -414,7 +430,7 @@ static int pmu_ctr_start_fw(uint32_t cidx, uint32_t event_code,
 int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
 		      unsigned long flags, uint64_t ival)
 {
-	u32 hartid = current_hartid();
+	struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
 	int event_idx_type;
 	uint32_t event_code;
 	int ret = SBI_EINVAL;
@@ -430,16 +446,16 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
 
 	for_each_set_bit(i, &cmask, total_ctrs) {
 		cidx = i + cbase;
-		event_idx_type = pmu_ctr_validate(cidx, &event_code);
+		event_idx_type = pmu_ctr_validate(phs, cidx, &event_code);
 		if (event_idx_type < 0)
 			/* Continue the start operation for other counters */
 			continue;
 		else if (event_idx_type == SBI_PMU_EVENT_TYPE_FW) {
 			edata = (event_code == SBI_PMU_FW_PLATFORM) ?
-				 fw_counters_data[hartid][cidx - num_hw_ctrs]
+				 phs->fw_counters_data[cidx - num_hw_ctrs]
 				 : 0x0;
-			ret = pmu_ctr_start_fw(cidx, event_code, edata, ival,
-					       bUpdate);
+			ret = pmu_ctr_start_fw(phs, cidx, event_code, edata,
+					       ival, bUpdate);
 		}
 		else
 			ret = pmu_ctr_start_hw(cidx, ival, bUpdate);
@@ -470,9 +486,9 @@ static int pmu_ctr_stop_hw(uint32_t cidx)
 		return SBI_EALREADY_STOPPED;
 }
 
-static int pmu_ctr_stop_fw(uint32_t cidx, uint32_t event_code)
+static int pmu_ctr_stop_fw(struct sbi_pmu_hart_state *phs,
+			   uint32_t cidx, uint32_t event_code)
 {
-	u32 hartid = current_hartid();
 	int ret;
 
 	if ((event_code >= SBI_PMU_FW_MAX &&
@@ -482,12 +498,12 @@ static int pmu_ctr_stop_fw(uint32_t cidx, uint32_t event_code)
 
 	if (SBI_PMU_FW_PLATFORM == event_code &&
 	    pmu_dev && pmu_dev->fw_counter_stop) {
-		ret = pmu_dev->fw_counter_stop(hartid, cidx - num_hw_ctrs);
+		ret = pmu_dev->fw_counter_stop(phs->hartid, cidx - num_hw_ctrs);
 		if (ret)
 			return ret;
 	}
 
-	fw_counters_started[current_hartid()] &= ~BIT(cidx - num_hw_ctrs);
+	phs->fw_counters_started &= ~BIT(cidx - num_hw_ctrs);
 
 	return 0;
 }
@@ -511,7 +527,7 @@ static int pmu_reset_hw_mhpmevent(int ctr_idx)
 int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
 		     unsigned long flag)
 {
-	u32 hartid = current_hartid();
+	struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
 	int ret = SBI_EINVAL;
 	int event_idx_type;
 	uint32_t event_code;
@@ -522,18 +538,18 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
 
 	for_each_set_bit(i, &cmask, total_ctrs) {
 		cidx = i + cbase;
-		event_idx_type = pmu_ctr_validate(cidx, &event_code);
+		event_idx_type = pmu_ctr_validate(phs, cidx, &event_code);
 		if (event_idx_type < 0)
 			/* Continue the stop operation for other counters */
 			continue;
 
 		else if (event_idx_type == SBI_PMU_EVENT_TYPE_FW)
-			ret = pmu_ctr_stop_fw(cidx, event_code);
+			ret = pmu_ctr_stop_fw(phs, cidx, event_code);
 		else
 			ret = pmu_ctr_stop_hw(cidx);
 
 		if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
-			active_events[hartid][cidx] = SBI_PMU_EVENT_IDX_INVALID;
+			phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
 			pmu_reset_hw_mhpmevent(cidx);
 		}
 	}
@@ -604,14 +620,15 @@ static int pmu_ctr_find_fixed_fw(unsigned long evt_idx_code)
 		return SBI_EINVAL;
 }
 
-static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, unsigned long flags,
+static int pmu_ctr_find_hw(struct sbi_pmu_hart_state *phs,
+			   unsigned long cbase, unsigned long cmask,
+			   unsigned long flags,
 			   unsigned long event_idx, uint64_t data)
 {
 	unsigned long ctr_mask;
 	int i, ret = 0, fixed_ctr, ctr_idx = SBI_ENOTSUPP;
 	struct sbi_pmu_hw_event *temp;
 	unsigned long mctr_inhbt = 0;
-	u32 hartid = current_hartid();
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
 	if (cbase >= num_hw_ctrs)
@@ -650,7 +667,7 @@ static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, unsigned lo
 			 * Some of the platform may not support mcountinhibit.
 			 * Checking the active_events is enough for them
 			 */
-			if (active_events[hartid][cbase] != SBI_PMU_EVENT_IDX_INVALID)
+			if (phs->active_events[cbase] != SBI_PMU_EVENT_IDX_INVALID)
 				continue;
 			/* If mcountinhibit is supported, the bit must be enabled */
 			if ((sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11) &&
@@ -685,8 +702,9 @@ static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, unsigned lo
  * Thus, select the first available fw counter after sanity
  * check.
  */
-static int pmu_ctr_find_fw(unsigned long cbase, unsigned long cmask,
-			   uint32_t event_code, u32 hartid, uint64_t edata)
+static int pmu_ctr_find_fw(struct sbi_pmu_hart_state *phs,
+			   unsigned long cbase, unsigned long cmask,
+			   uint32_t event_code, uint64_t edata)
 {
 	int i, cidx;
 
@@ -699,11 +717,11 @@ static int pmu_ctr_find_fw(unsigned long cbase, unsigned long cmask,
 		cidx = i + cbase;
 		if (cidx < num_hw_ctrs || total_ctrs <= cidx)
 			continue;
-		if (active_events[hartid][i] != SBI_PMU_EVENT_IDX_INVALID)
+		if (phs->active_events[i] != SBI_PMU_EVENT_IDX_INVALID)
 			continue;
 		if (SBI_PMU_FW_PLATFORM == event_code &&
 		    pmu_dev && pmu_dev->fw_counter_match_encoding) {
-			if (!pmu_dev->fw_counter_match_encoding(hartid,
+			if (!pmu_dev->fw_counter_match_encoding(phs->hartid,
 							    cidx - num_hw_ctrs,
 							    edata))
 				continue;
@@ -719,15 +737,15 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
 			  unsigned long flags, unsigned long event_idx,
 			  uint64_t event_data)
 {
-	int ret, ctr_idx = SBI_ENOTSUPP;
-	u32 event_code, hartid = current_hartid();
-	int event_type;
+	struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
+	int ret, event_type, ctr_idx = SBI_ENOTSUPP;
+	u32 event_code;
 
 	/* Do a basic sanity check of counter base & mask */
 	if ((cidx_base + sbi_fls(cidx_mask)) >= total_ctrs)
 		return SBI_EINVAL;
 
-	event_type = pmu_event_validate(event_idx, event_data);
+	event_type = pmu_event_validate(phs, event_idx, event_data);
 	if (event_type < 0)
 		return SBI_EINVAL;
 	event_code = get_cidx_code(event_idx);
@@ -742,7 +760,7 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
 		 */
 		unsigned long cidx_first = cidx_base + sbi_ffs(cidx_mask);
 
-		if (active_events[hartid][cidx_first] == SBI_PMU_EVENT_IDX_INVALID)
+		if (phs->active_events[cidx_first] == SBI_PMU_EVENT_IDX_INVALID)
 			return SBI_EINVAL;
 		ctr_idx = cidx_first;
 		goto skip_match;
@@ -750,20 +768,20 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
 
 	if (event_type == SBI_PMU_EVENT_TYPE_FW) {
 		/* Any firmware counter can be used track any firmware event */
-		ctr_idx = pmu_ctr_find_fw(cidx_base, cidx_mask, event_code,
-					  hartid, event_data);
+		ctr_idx = pmu_ctr_find_fw(phs, cidx_base, cidx_mask,
+					  event_code, event_data);
 		if (event_code == SBI_PMU_FW_PLATFORM)
-			fw_counters_data[hartid][ctr_idx - num_hw_ctrs] =
+			phs->fw_counters_data[ctr_idx - num_hw_ctrs] =
 								event_data;
 	} else {
-		ctr_idx = pmu_ctr_find_hw(cidx_base, cidx_mask, flags, event_idx,
-					  event_data);
+		ctr_idx = pmu_ctr_find_hw(phs, cidx_base, cidx_mask, flags,
+					  event_idx, event_data);
 	}
 
 	if (ctr_idx < 0)
 		return SBI_ENOTSUPP;
 
-	active_events[hartid][ctr_idx] = event_idx;
+	phs->active_events[ctr_idx] = event_idx;
 skip_match:
 	if (event_type == SBI_PMU_EVENT_TYPE_HW) {
 		if (flags & SBI_PMU_CFG_FLAG_CLEAR_VALUE)
@@ -772,16 +790,17 @@ skip_match:
 			pmu_ctr_start_hw(ctr_idx, 0, false);
 	} else if (event_type == SBI_PMU_EVENT_TYPE_FW) {
 		if (flags & SBI_PMU_CFG_FLAG_CLEAR_VALUE)
-			fw_counters_data[hartid][ctr_idx - num_hw_ctrs] = 0;
+			phs->fw_counters_data[ctr_idx - num_hw_ctrs] = 0;
 		if (flags & SBI_PMU_CFG_FLAG_AUTO_START) {
 			if (SBI_PMU_FW_PLATFORM == event_code &&
 			    pmu_dev && pmu_dev->fw_counter_start) {
-				ret = pmu_dev->fw_counter_start(hartid,
+				ret = pmu_dev->fw_counter_start(
+					phs->hartid,
 					ctr_idx - num_hw_ctrs, event_data);
 				if (ret)
 					return ret;
 			}
-			fw_counters_started[hartid] |= BIT(ctr_idx - num_hw_ctrs);
+			phs->fw_counters_started |= BIT(ctr_idx - num_hw_ctrs);
 		}
 	}
 
@@ -790,19 +809,20 @@ skip_match:
 
 int sbi_pmu_ctr_incr_fw(enum sbi_pmu_fw_event_code_id fw_id)
 {
-	u32 cidx, hartid = current_hartid();
+	u32 cidx;
 	uint64_t *fcounter = NULL;
+	struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
 
-	if (likely(!fw_counters_started[hartid]))
+	if (likely(!phs->fw_counters_started))
 		return 0;
 
 	if (unlikely(fw_id >= SBI_PMU_FW_MAX))
 		return SBI_EINVAL;
 
 	for (cidx = num_hw_ctrs; cidx < total_ctrs; cidx++) {
-		if (get_cidx_code(active_events[hartid][cidx]) == fw_id &&
-		    (fw_counters_started[hartid] & BIT(cidx - num_hw_ctrs))) {
-			fcounter = &fw_counters_data[hartid][cidx - num_hw_ctrs];
+		if (get_cidx_code(phs->active_events[cidx]) == fw_id &&
+		    (phs->fw_counters_started & BIT(cidx - num_hw_ctrs))) {
+			fcounter = &phs->fw_counters_data[cidx - num_hw_ctrs];
 			break;
 		}
 	}
@@ -854,16 +874,16 @@ int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info)
 	return 0;
 }
 
-static void pmu_reset_event_map(u32 hartid)
+static void pmu_reset_event_map(struct sbi_pmu_hart_state *phs)
 {
 	int j;
 
 	/* Initialize the counter to event mapping table */
 	for (j = 3; j < total_ctrs; j++)
-		active_events[hartid][j] = SBI_PMU_EVENT_IDX_INVALID;
+		phs->active_events[j] = SBI_PMU_EVENT_IDX_INVALID;
 	for (j = 0; j < SBI_PMU_FW_CTR_MAX; j++)
-		fw_counters_data[hartid][j] = 0;
-	fw_counters_started[hartid] = 0;
+		phs->fw_counters_data[j] = 0;
+	phs->fw_counters_started = 0;
 }
 
 const struct sbi_pmu_device *sbi_pmu_get_device(void)
@@ -881,22 +901,32 @@ void sbi_pmu_set_device(const struct sbi_pmu_device *dev)
 
 void sbi_pmu_exit(struct sbi_scratch *scratch)
 {
-	u32 hartid = current_hartid();
-
 	if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11)
 		csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8);
 
 	if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
 		csr_write(CSR_MCOUNTEREN, -1);
-	pmu_reset_event_map(hartid);
+
+	pmu_reset_event_map(pmu_get_hart_state_ptr(scratch));
 }
 
 int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
 {
+	struct sbi_pmu_hart_state *phs;
 	const struct sbi_platform *plat;
-	u32 hartid = current_hartid();
 
 	if (cold_boot) {
+		hw_event_map = sbi_calloc(sizeof(*hw_event_map),
+					  SBI_PMU_HW_EVENT_MAX);
+		if (!hw_event_map)
+			return SBI_ENOMEM;
+
+		phs_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+		if (!phs_ptr_offset) {
+			sbi_free(hw_event_map);
+			return SBI_ENOMEM;
+		}
+
 		plat = sbi_platform_ptr(scratch);
 		/* Initialize hw pmu events */
 		sbi_platform_pmu_init(plat);
@@ -906,14 +936,23 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
 		total_ctrs = num_hw_ctrs + SBI_PMU_FW_CTR_MAX;
 	}
 
-	pmu_reset_event_map(hartid);
+	phs = pmu_get_hart_state_ptr(scratch);
+	if (!phs) {
+		phs = sbi_zalloc(sizeof(*phs));
+		if (!phs)
+			return SBI_ENOMEM;
+		phs->hartid = current_hartid();
+		pmu_set_hart_state_ptr(scratch, phs);
+	}
+
+	pmu_reset_event_map(phs);
 
 	/* First three counters are fixed by the priv spec and we enable it by default */
-	active_events[hartid][0] = SBI_PMU_EVENT_TYPE_HW << SBI_PMU_EVENT_IDX_TYPE_OFFSET |
-				   SBI_PMU_HW_CPU_CYCLES;
-	active_events[hartid][1] = SBI_PMU_EVENT_IDX_INVALID;
-	active_events[hartid][2] = SBI_PMU_EVENT_TYPE_HW << SBI_PMU_EVENT_IDX_TYPE_OFFSET |
-				   SBI_PMU_HW_INSTRUCTIONS;
+	phs->active_events[0] = (SBI_PMU_EVENT_TYPE_HW << SBI_PMU_EVENT_IDX_TYPE_OFFSET) |
+				SBI_PMU_HW_CPU_CYCLES;
+	phs->active_events[1] = SBI_PMU_EVENT_IDX_INVALID;
+	phs->active_events[2] = (SBI_PMU_EVENT_TYPE_HW << SBI_PMU_EVENT_IDX_TYPE_OFFSET) |
+				SBI_PMU_HW_INSTRUCTIONS;
 
 	return 0;
 }
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:37 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:37 +0530
Subject: [PATCH v2 06/18] lib: sbi: Use heap for root domain creation
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-7-apatel@ventanamicro.com>

Let's use heap allocation in root domain creation instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/sbi/sbi_domain.c | 45 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index c55e192..5800870 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -11,6 +11,7 @@
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_domain.h>
 #include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hsm.h>
 #include <sbi/sbi_math.h>
 #include <sbi/sbi_platform.h>
@@ -26,16 +27,13 @@ struct sbi_domain *hartid_to_domain_table[SBI_HARTMASK_MAX_BITS] = { 0 };
 static u32 domain_count = 0;
 static bool domain_finalized = false;
 
-static struct sbi_hartmask root_hmask = { 0 };
-
 #define ROOT_REGION_MAX	16
 static u32 root_memregs_count = 0;
-static struct sbi_domain_memregion root_memregs[ROOT_REGION_MAX + 1] = { 0 };
 
 struct sbi_domain root = {
 	.name = "root",
-	.possible_harts = &root_hmask,
-	.regions = root_memregs,
+	.possible_harts = NULL,
+	.regions = NULL,
 	.system_reset_allowed = true,
 	.system_suspend_allowed = true,
 	.fw_region_inited = false,
@@ -551,8 +549,7 @@ int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg)
 	const struct sbi_platform *plat = sbi_platform_thishart_ptr();
 
 	/* Sanity checks */
-	if (!reg || domain_finalized ||
-	    (root.regions != root_memregs) ||
+	if (!reg || domain_finalized || !root.regions ||
 	    (ROOT_REGION_MAX <= root_memregs_count))
 		return SBI_EINVAL;
 
@@ -567,10 +564,10 @@ int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg)
 	}
 
 	/* Append the memregion to root memregions */
-	nreg = &root_memregs[root_memregs_count];
+	nreg = &root.regions[root_memregs_count];
 	sbi_memcpy(nreg, reg, sizeof(*reg));
 	root_memregs_count++;
-	root_memregs[root_memregs_count].order = 0;
+	root.regions[root_memregs_count].order = 0;
 
 	/* Sort and optimize root regions */
 	do {
@@ -700,6 +697,9 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
 int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 {
 	u32 i;
+	int rc;
+	struct sbi_hartmask *root_hmask;
+	struct sbi_domain_memregion *root_memregs;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
 	if (scratch->fw_rw_offset == 0 ||
@@ -715,6 +715,21 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 		return SBI_EINVAL;
 	}
 
+	root_memregs = sbi_calloc(sizeof(*root_memregs), ROOT_REGION_MAX + 1);
+	if (!root_memregs) {
+		sbi_printf("%s: no memory for root regions\n", __func__);
+		return SBI_ENOMEM;
+	}
+	root.regions = root_memregs;
+
+	root_hmask = sbi_zalloc(sizeof(*root_hmask));
+	if (!root_hmask) {
+		sbi_printf("%s: no memory for root hartmask\n", __func__);
+		sbi_free(root_memregs);
+		return SBI_ENOMEM;
+	}
+	root.possible_harts = root_hmask;
+
 	/* Root domain firmware memory region */
 	sbi_domain_memregion_init(scratch->fw_start, scratch->fw_rw_offset,
 				  (SBI_DOMAIN_MEMREGION_M_READABLE |
@@ -751,8 +766,16 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 	for (i = 0; i < SBI_HARTMASK_MAX_BITS; i++) {
 		if (sbi_platform_hart_invalid(plat, i))
 			continue;
-		sbi_hartmask_set_hart(i, &root_hmask);
+		sbi_hartmask_set_hart(i, root_hmask);
+	}
+
+	/* Finally register the root domain */
+	rc = sbi_domain_register(&root, root_hmask);
+	if (rc) {
+		sbi_free(root_hmask);
+		sbi_free(root_memregs);
+		return rc;
 	}
 
-	return sbi_domain_register(&root, &root_hmask);
+	return 0;
 }
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:38 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:38 +0530
Subject: [PATCH v2 07/18] lib: sbi: Use scratch space to save per-HART domain pointer
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-8-apatel@ventanamicro.com>

Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART domain pointer.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/sbi/sbi_domain.h |  6 +----
 lib/sbi/sbi_domain.c     | 55 ++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 124ea90..b05bcf4 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -129,12 +129,8 @@ struct sbi_domain {
 /** The root domain instance */
 extern struct sbi_domain root;
 
-/** HART id to domain table */
-extern struct sbi_domain *hartid_to_domain_table[];
-
 /** Get pointer to sbi_domain from HART id */
-#define sbi_hartid_to_domain(__hartid) \
-	hartid_to_domain_table[__hartid]
+struct sbi_domain *sbi_hartid_to_domain(u32 hartid);
 
 /** Get pointer to sbi_domain for current HART */
 #define sbi_domain_thishart_ptr() \
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 5800870..38a5902 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -23,7 +23,6 @@
  * the array to be null-terminated.
  */
 struct sbi_domain *domidx_to_domain_table[SBI_DOMAIN_MAX_INDEX + 1] = { 0 };
-struct sbi_domain *hartid_to_domain_table[SBI_HARTMASK_MAX_BITS] = { 0 };
 static u32 domain_count = 0;
 static bool domain_finalized = false;
 
@@ -39,6 +38,30 @@ struct sbi_domain root = {
 	.fw_region_inited = false,
 };
 
+static unsigned long domain_hart_ptr_offset;
+
+struct sbi_domain *sbi_hartid_to_domain(u32 hartid)
+{
+	struct sbi_scratch *scratch;
+
+	scratch = sbi_hartid_to_scratch(hartid);
+	if (!scratch || !domain_hart_ptr_offset)
+		return NULL;
+
+	return sbi_scratch_read_type(scratch, void *, domain_hart_ptr_offset);
+}
+
+static void update_hartid_to_domain(u32 hartid, struct sbi_domain *dom)
+{
+	struct sbi_scratch *scratch;
+
+	scratch = sbi_hartid_to_scratch(hartid);
+	if (!scratch)
+		return;
+
+	sbi_scratch_write_type(scratch, void *, domain_hart_ptr_offset, dom);
+}
+
 bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid)
 {
 	if (dom)
@@ -519,11 +542,11 @@ int sbi_domain_register(struct sbi_domain *dom,
 		if (!sbi_hartmask_test_hart(i, dom->possible_harts))
 			continue;
 
-		tdom = hartid_to_domain_table[i];
+		tdom = sbi_hartid_to_domain(i);
 		if (tdom)
 			sbi_hartmask_clear_hart(i,
 					&tdom->assigned_harts);
-		hartid_to_domain_table[i] = dom;
+		update_hartid_to_domain(i, dom);
 		sbi_hartmask_set_hart(i, &dom->assigned_harts);
 
 		/*
@@ -715,18 +738,23 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 		return SBI_EINVAL;
 	}
 
+	domain_hart_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+	if (!domain_hart_ptr_offset)
+		return SBI_ENOMEM;
+
 	root_memregs = sbi_calloc(sizeof(*root_memregs), ROOT_REGION_MAX + 1);
 	if (!root_memregs) {
 		sbi_printf("%s: no memory for root regions\n", __func__);
-		return SBI_ENOMEM;
+		rc = SBI_ENOMEM;
+		goto fail_free_domain_hart_ptr_offset;
 	}
 	root.regions = root_memregs;
 
 	root_hmask = sbi_zalloc(sizeof(*root_hmask));
 	if (!root_hmask) {
 		sbi_printf("%s: no memory for root hartmask\n", __func__);
-		sbi_free(root_memregs);
-		return SBI_ENOMEM;
+		rc = SBI_ENOMEM;
+		goto fail_free_root_memregs;
 	}
 	root.possible_harts = root_hmask;
 
@@ -771,11 +799,16 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 
 	/* Finally register the root domain */
 	rc = sbi_domain_register(&root, root_hmask);
-	if (rc) {
-		sbi_free(root_hmask);
-		sbi_free(root_memregs);
-		return rc;
-	}
+	if (rc)
+		goto fail_free_root_hmask;
 
 	return 0;
+
+fail_free_root_hmask:
+	sbi_free(root_hmask);
+fail_free_root_memregs:
+	sbi_free(root_memregs);
+fail_free_domain_hart_ptr_offset:
+	sbi_scratch_free_offset(domain_hart_ptr_offset);
+	return rc;
 }
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:39 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:39 +0530
Subject: [PATCH v2 08/18] lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-9-apatel@ventanamicro.com>

Let's use heap allocation in SiFive and Starfive GPIO drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/gpio/fdt_gpio_sifive.c   | 21 ++++++++++-----------
 lib/utils/gpio/fdt_gpio_starfive.c | 20 ++++++++++----------
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/lib/utils/gpio/fdt_gpio_sifive.c b/lib/utils/gpio/fdt_gpio_sifive.c
index 677f0fa..5e3f39d 100644
--- a/lib/utils/gpio/fdt_gpio_sifive.c
+++ b/lib/utils/gpio/fdt_gpio_sifive.c
@@ -9,11 +9,10 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/gpio/fdt_gpio.h>
 
-#define SIFIVE_GPIO_CHIP_MAX	2
-
 #define SIFIVE_GPIO_PINS_MIN	1
 #define SIFIVE_GPIO_PINS_MAX	32
 #define SIFIVE_GPIO_PINS_DEF	16
@@ -27,9 +26,6 @@ struct sifive_gpio_chip {
 	struct gpio_chip chip;
 };
 
-static unsigned int sifive_gpio_chip_count;
-static struct sifive_gpio_chip sifive_gpio_chip_array[SIFIVE_GPIO_CHIP_MAX];
-
 static int sifive_gpio_direction_output(struct gpio_pin *gp, int value)
 {
 	unsigned int v;
@@ -73,13 +69,15 @@ static int sifive_gpio_init(void *fdt, int nodeoff, u32 phandle,
 	struct sifive_gpio_chip *chip;
 	uint64_t addr;
 
-	if (SIFIVE_GPIO_CHIP_MAX <= sifive_gpio_chip_count)
-		return SBI_ENOSPC;
-	chip = &sifive_gpio_chip_array[sifive_gpio_chip_count];
+	chip = sbi_zalloc(sizeof(*chip));
+	if (!chip)
+		return SBI_ENOMEM;
 
 	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-	if (rc)
+	if (rc) {
+		sbi_free(chip);
 		return rc;
+	}
 
 	chip->addr = addr;
 	chip->chip.driver = &fdt_gpio_sifive;
@@ -88,10 +86,11 @@ static int sifive_gpio_init(void *fdt, int nodeoff, u32 phandle,
 	chip->chip.direction_output = sifive_gpio_direction_output;
 	chip->chip.set = sifive_gpio_set;
 	rc = gpio_chip_add(&chip->chip);
-	if (rc)
+	if (rc) {
+		sbi_free(chip);
 		return rc;
+	}
 
-	sifive_gpio_chip_count++;
 	return 0;
 }
 
diff --git a/lib/utils/gpio/fdt_gpio_starfive.c b/lib/utils/gpio/fdt_gpio_starfive.c
index 18cca72..f430b13 100644
--- a/lib/utils/gpio/fdt_gpio_starfive.c
+++ b/lib/utils/gpio/fdt_gpio_starfive.c
@@ -9,11 +9,11 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_console.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/gpio/fdt_gpio.h>
 
-#define STARFIVE_GPIO_CHIP_MAX		2
 #define STARFIVE_GPIO_PINS_DEF		64
 #define STARFIVE_GPIO_OUTVAL		0x40
 #define STARFIVE_GPIO_MASK		0xff
@@ -25,9 +25,6 @@ struct starfive_gpio_chip {
 	struct gpio_chip chip;
 };
 
-static unsigned int starfive_gpio_chip_count;
-static struct starfive_gpio_chip starfive_gpio_chip_array[STARFIVE_GPIO_CHIP_MAX];
-
 static int starfive_gpio_direction_output(struct gpio_pin *gp, int value)
 {
 	u32 val;
@@ -82,13 +79,15 @@ static int starfive_gpio_init(void *fdt, int nodeoff, u32 phandle,
 	struct starfive_gpio_chip *chip;
 	u64 addr;
 
-	if (starfive_gpio_chip_count >= STARFIVE_GPIO_CHIP_MAX)
-		return SBI_ENOSPC;
-	chip = &starfive_gpio_chip_array[starfive_gpio_chip_count];
+	chip = sbi_zalloc(sizeof(*chip));
+	if (!chip)
+		return SBI_ENOMEM;
 
 	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-	if (rc)
+	if (rc) {
+		sbi_free(chip);
 		return rc;
+	}
 
 	chip->addr = addr;
 	chip->chip.driver = &fdt_gpio_starfive;
@@ -97,10 +96,11 @@ static int starfive_gpio_init(void *fdt, int nodeoff, u32 phandle,
 	chip->chip.direction_output = starfive_gpio_direction_output;
 	chip->chip.set = starfive_gpio_set;
 	rc = gpio_chip_add(&chip->chip);
-	if (rc)
+	if (rc) {
+		sbi_free(chip);
 		return rc;
+	}
 
-	starfive_gpio_chip_count++;
 	return 0;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:40 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:40 +0530
Subject: [PATCH v2 09/18] lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-10-apatel@ventanamicro.com>

Let's use heap allocation in DesignWare and SiFive I2C drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/i2c/fdt_i2c_dw.c     | 24 ++++++++++--------------
 lib/utils/i2c/fdt_i2c_sifive.c | 23 ++++++++++-------------
 2 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/lib/utils/i2c/fdt_i2c_dw.c b/lib/utils/i2c/fdt_i2c_dw.c
index 71062f4..99b2ddb 100644
--- a/lib/utils/i2c/fdt_i2c_dw.c
+++ b/lib/utils/i2c/fdt_i2c_dw.c
@@ -9,17 +9,12 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_string.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/i2c/dw_i2c.h>
 #include <sbi_utils/i2c/fdt_i2c.h>
 
-#define FDT_DW_I2C_ADAPTER_MAX	7
-
-static unsigned int fdt_dw_i2c_adapter_count;
-static struct dw_i2c_adapter
-	fdt_dw_i2c_adapter_array[FDT_DW_I2C_ADAPTER_MAX];
-
 extern struct fdt_i2c_adapter fdt_i2c_adapter_dw;
 
 static int fdt_dw_i2c_init(void *fdt, int nodeoff,
@@ -29,23 +24,24 @@ static int fdt_dw_i2c_init(void *fdt, int nodeoff,
 	struct dw_i2c_adapter *adapter;
 	u64 addr;
 
-	if (fdt_dw_i2c_adapter_count >= FDT_DW_I2C_ADAPTER_MAX)
-		return SBI_ENOSPC;
-
-	adapter = &fdt_dw_i2c_adapter_array[fdt_dw_i2c_adapter_count];
+	adapter = sbi_zalloc(sizeof(*adapter));
+	if (!adapter)
+		return SBI_ENOMEM;
 
 	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-	if (rc)
+	if (rc) {
+		sbi_free(adapter);
 		return rc;
+	}
 
 	adapter->addr = addr;
 	adapter->adapter.driver = &fdt_i2c_adapter_dw;
 
 	rc = dw_i2c_init(&adapter->adapter, nodeoff);
-	if (rc)
+	if (rc) {
+		sbi_free(adapter);
 		return rc;
-
-	fdt_dw_i2c_adapter_count++;
+	}
 
 	return 0;
 }
diff --git a/lib/utils/i2c/fdt_i2c_sifive.c b/lib/utils/i2c/fdt_i2c_sifive.c
index 195541c..b85b245 100644
--- a/lib/utils/i2c/fdt_i2c_sifive.c
+++ b/lib/utils/i2c/fdt_i2c_sifive.c
@@ -9,12 +9,11 @@
 
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_timer.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/i2c/fdt_i2c.h>
 
-#define SIFIVE_I2C_ADAPTER_MAX	2
-
 #define SIFIVE_I2C_PRELO	0x00
 #define SIFIVE_I2C_PREHI	0x04
 #define SIFIVE_I2C_CTR		0x08
@@ -47,10 +46,6 @@ struct sifive_i2c_adapter {
 	struct i2c_adapter adapter;
 };
 
-static unsigned int sifive_i2c_adapter_count;
-static struct sifive_i2c_adapter
-	sifive_i2c_adapter_array[SIFIVE_I2C_ADAPTER_MAX];
-
 extern struct fdt_i2c_adapter fdt_i2c_adapter_sifive;
 
 static inline void sifive_i2c_setreg(struct sifive_i2c_adapter *adap,
@@ -244,14 +239,15 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
 	struct sifive_i2c_adapter *adapter;
 	uint64_t addr;
 
-	if (sifive_i2c_adapter_count >= SIFIVE_I2C_ADAPTER_MAX)
-		return SBI_ENOSPC;
-
-	adapter = &sifive_i2c_adapter_array[sifive_i2c_adapter_count];
+	adapter = sbi_zalloc(sizeof(*adapter));
+	if (!adapter)
+		return SBI_ENOMEM;
 
 	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
-	if (rc)
+	if (rc) {
+		sbi_free(adapter);
 		return rc;
+	}
 
 	adapter->addr = addr;
 	adapter->adapter.driver = &fdt_i2c_adapter_sifive;
@@ -259,10 +255,11 @@ static int sifive_i2c_init(void *fdt, int nodeoff,
 	adapter->adapter.write = sifive_i2c_adapter_write;
 	adapter->adapter.read = sifive_i2c_adapter_read;
 	rc = i2c_adapter_add(&adapter->adapter);
-	if (rc)
+	if (rc) {
+		sbi_free(adapter);
 		return rc;
+	}
 
-	sifive_i2c_adapter_count++;
 	return 0;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:46 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:46 +0530
Subject: [PATCH v2 15/18] lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-16-apatel@ventanamicro.com>

Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART MTIMER pointer.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/timer/aclint_mtimer.c | 76 ++++++++++++++++++++++++++-------
 1 file changed, 61 insertions(+), 15 deletions(-)

diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c
index 84ded4e..13af5d8 100644
--- a/lib/utils/timer/aclint_mtimer.c
+++ b/lib/utils/timer/aclint_mtimer.c
@@ -13,12 +13,17 @@
 #include <sbi/sbi_bitops.h>
 #include <sbi/sbi_domain.h>
 #include <sbi/sbi_error.h>
-#include <sbi/sbi_hartmask.h>
-#include <sbi/sbi_ipi.h>
+#include <sbi/sbi_scratch.h>
 #include <sbi/sbi_timer.h>
 #include <sbi_utils/timer/aclint_mtimer.h>
 
-static struct aclint_mtimer_data *mtimer_hartid2data[SBI_HARTMASK_MAX_BITS];
+static unsigned long mtimer_ptr_offset;
+
+#define mtimer_get_hart_data_ptr(__scratch)				\
+	sbi_scratch_read_type((__scratch), void *, mtimer_ptr_offset)
+
+#define mtimer_set_hart_data_ptr(__scratch, __mtimer)			\
+	sbi_scratch_write_type((__scratch), void *, mtimer_ptr_offset, (__mtimer))
 
 #if __riscv_xlen != 32
 static u64 mtimer_time_rd64(volatile u64 *addr)
@@ -53,30 +58,54 @@ static void mtimer_time_wr32(bool timecmp, u64 value, volatile u64 *addr)
 
 static u64 mtimer_value(void)
 {
-	struct aclint_mtimer_data *mt = mtimer_hartid2data[current_hartid()];
-	u64 *time_val = (void *)mt->mtime_addr;
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct aclint_mtimer_data *mt;
+
+	mt = mtimer_get_hart_data_ptr(scratch);
+	if (!mt)
+		return 0;
 
 	/* Read MTIMER Time Value */
-	return mt->time_rd(time_val);
+	return mt->time_rd((void *)mt->mtime_addr);
 }
 
 static void mtimer_event_stop(void)
 {
 	u32 target_hart = current_hartid();
-	struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart];
-	u64 *time_cmp = (void *)mt->mtimecmp_addr;
+	struct sbi_scratch *scratch;
+	struct aclint_mtimer_data *mt;
+	u64 *time_cmp;
+
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
+		return;
+
+	mt = mtimer_get_hart_data_ptr(scratch);
+	if (!mt)
+		return;
 
 	/* Clear MTIMER Time Compare */
+	time_cmp = (void *)mt->mtimecmp_addr;
 	mt->time_wr(true, -1ULL, &time_cmp[target_hart - mt->first_hartid]);
 }
 
 static void mtimer_event_start(u64 next_event)
 {
 	u32 target_hart = current_hartid();
-	struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart];
-	u64 *time_cmp = (void *)mt->mtimecmp_addr;
+	struct sbi_scratch *scratch;
+	struct aclint_mtimer_data *mt;
+	u64 *time_cmp;
+
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
+		return;
+
+	mt = mtimer_get_hart_data_ptr(scratch);
+	if (!mt)
+		return;
 
 	/* Program MTIMER Time Compare */
+	time_cmp = (void *)mt->mtimecmp_addr;
 	mt->time_wr(true, next_event,
 		    &time_cmp[target_hart - mt->first_hartid]);
 }
@@ -126,8 +155,14 @@ int aclint_mtimer_warm_init(void)
 {
 	u64 *mt_time_cmp;
 	u32 target_hart = current_hartid();
-	struct aclint_mtimer_data *mt = mtimer_hartid2data[target_hart];
+	struct sbi_scratch *scratch;
+	struct aclint_mtimer_data *mt;
 
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
+		return SBI_ENOENT;
+
+	mt = mtimer_get_hart_data_ptr(scratch);
 	if (!mt)
 		return SBI_ENODEV;
 
@@ -147,6 +182,7 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt,
 {
 	u32 i;
 	int rc;
+	struct sbi_scratch *scratch;
 
 	/* Sanity checks */
 	if (!mt ||
@@ -155,12 +191,18 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt,
 	    (mt->mtime_size && (mt->mtime_size & (ACLINT_MTIMER_ALIGN - 1))) ||
 	    (mt->mtimecmp_addr & (ACLINT_MTIMER_ALIGN - 1)) ||
 	    (mt->mtimecmp_size & (ACLINT_MTIMER_ALIGN - 1)) ||
-	    (mt->first_hartid >= SBI_HARTMASK_MAX_BITS) ||
 	    (mt->hart_count > ACLINT_MTIMER_MAX_HARTS))
 		return SBI_EINVAL;
 	if (reference && mt->mtime_freq != reference->mtime_freq)
 		return SBI_EINVAL;
 
+	/* Allocate scratch space pointer */
+	if (!mtimer_ptr_offset) {
+		mtimer_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+		if (!mtimer_ptr_offset)
+			return SBI_ENOMEM;
+	}
+
 	/* Initialize private data */
 	aclint_mtimer_set_reference(mt, reference);
 	mt->time_rd = mtimer_time_rd32;
@@ -174,9 +216,13 @@ int aclint_mtimer_cold_init(struct aclint_mtimer_data *mt,
 	}
 #endif
 
-	/* Update MTIMER hartid table */
-	for (i = 0; i < mt->hart_count; i++)
-		mtimer_hartid2data[mt->first_hartid + i] = mt;
+	/* Update MTIMER pointer in scratch space */
+	for (i = 0; i < mt->hart_count; i++) {
+		scratch = sbi_hartid_to_scratch(mt->first_hartid + i);
+		if (!scratch)
+			return SBI_ENOENT;
+		mtimer_set_hart_data_ptr(scratch, mt);
+	}
 
 	if (!mt->mtime_size) {
 		/* Disable reading mtime when mtime is not available */
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:48 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:48 +0530
Subject: [PATCH v2 17/18] lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-18-apatel@ventanamicro.com>

The imsic_map_hartid_to_data() already checks hartid before using
so we don't need to check in imsic_update_hartid_table().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/irqchip/fdt_irqchip_imsic.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/lib/utils/irqchip/fdt_irqchip_imsic.c b/lib/utils/irqchip/fdt_irqchip_imsic.c
index 590b202..d032ac8 100644
--- a/lib/utils/irqchip/fdt_irqchip_imsic.c
+++ b/lib/utils/irqchip/fdt_irqchip_imsic.c
@@ -12,7 +12,6 @@
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_heap.h>
-#include <sbi/sbi_hartmask.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/imsic.h>
@@ -44,8 +43,6 @@ static int irqchip_imsic_update_hartid_table(void *fdt, int nodeoff,
 		err = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
 		if (err)
 			return SBI_EINVAL;
-		if (SBI_HARTMASK_MAX_BITS <= hartid)
-			return SBI_EINVAL;
 
 		switch (hwirq) {
 		case IRQ_M_EXT:
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:49 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:49 +0530
Subject: [PATCH v2 18/18] lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-19-apatel@ventanamicro.com>

Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART IMSIC pointer and IMSIC file number.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/irqchip/fdt_irqchip_imsic.c |  4 +-
 lib/utils/irqchip/imsic.c             | 76 +++++++++++++++++++++------
 2 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/lib/utils/irqchip/fdt_irqchip_imsic.c b/lib/utils/irqchip/fdt_irqchip_imsic.c
index d032ac8..4eb1854 100644
--- a/lib/utils/irqchip/fdt_irqchip_imsic.c
+++ b/lib/utils/irqchip/fdt_irqchip_imsic.c
@@ -72,11 +72,11 @@ static int irqchip_imsic_cold_init(void *fdt, int nodeoff,
 	if (rc || !id->targets_mmode)
 		goto fail_free_data;
 
-	rc = irqchip_imsic_update_hartid_table(fdt, nodeoff, id);
+	rc = imsic_cold_irqchip_init(id);
 	if (rc)
 		goto fail_free_data;
 
-	rc = imsic_cold_irqchip_init(id);
+	rc = irqchip_imsic_update_hartid_table(fdt, nodeoff, id);
 	if (rc)
 		goto fail_free_data;
 
diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c
index 11667cd..3685343 100644
--- a/lib/utils/irqchip/imsic.c
+++ b/lib/utils/irqchip/imsic.c
@@ -13,10 +13,10 @@
 #include <sbi/riscv_encoding.h>
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_domain.h>
-#include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_ipi.h>
 #include <sbi/sbi_irqchip.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_scratch.h>
 #include <sbi_utils/irqchip/imsic.h>
 
 #define IMSIC_MMIO_PAGE_LE		0x00
@@ -79,33 +79,58 @@ do { \
 	csr_clear(CSR_MIREG, __v); \
 } while (0)
 
-static struct imsic_data *imsic_hartid2data[SBI_HARTMASK_MAX_BITS];
-static int imsic_hartid2file[SBI_HARTMASK_MAX_BITS];
+static unsigned long imsic_ptr_offset;
+
+#define imsic_get_hart_data_ptr(__scratch)				\
+	sbi_scratch_read_type((__scratch), void *, imsic_ptr_offset)
+
+#define imsic_set_hart_data_ptr(__scratch, __imsic)			\
+	sbi_scratch_write_type((__scratch), void *, imsic_ptr_offset, (__imsic))
+
+static unsigned long imsic_file_offset;
+
+#define imsic_get_hart_file(__scratch)					\
+	sbi_scratch_read_type((__scratch), long, imsic_file_offset)
+
+#define imsic_set_hart_file(__scratch, __file)				\
+	sbi_scratch_write_type((__scratch), long, imsic_file_offset, (__file))
 
 int imsic_map_hartid_to_data(u32 hartid, struct imsic_data *imsic, int file)
 {
-	if (!imsic || !imsic->targets_mmode ||
-	    (SBI_HARTMASK_MAX_BITS <= hartid))
+	struct sbi_scratch *scratch;
+
+	if (!imsic || !imsic->targets_mmode)
 		return SBI_EINVAL;
 
-	imsic_hartid2data[hartid] = imsic;
-	imsic_hartid2file[hartid] = file;
+	scratch = sbi_hartid_to_scratch(hartid);
+	if (!scratch)
+		return SBI_ENOENT;
+
+	imsic_set_hart_data_ptr(scratch, imsic);
+	imsic_set_hart_file(scratch, file);
 	return 0;
 }
 
 struct imsic_data *imsic_get_data(u32 hartid)
 {
-	if (SBI_HARTMASK_MAX_BITS <= hartid)
+	struct sbi_scratch *scratch;
+
+	scratch = sbi_hartid_to_scratch(hartid);
+	if (!scratch)
 		return NULL;
-	return imsic_hartid2data[hartid];
+
+	return imsic_get_hart_data_ptr(scratch);
 }
 
 int imsic_get_target_file(u32 hartid)
 {
-	if ((SBI_HARTMASK_MAX_BITS <= hartid) ||
-	    !imsic_hartid2data[hartid])
+	struct sbi_scratch *scratch;
+
+	scratch = sbi_hartid_to_scratch(hartid);
+	if (!scratch)
 		return SBI_ENOENT;
-	return imsic_hartid2file[hartid];
+
+	return imsic_get_hart_file(scratch);
 }
 
 static int imsic_external_irqfn(struct sbi_trap_regs *regs)
@@ -133,9 +158,16 @@ static void imsic_ipi_send(u32 target_hart)
 {
 	unsigned long reloff;
 	struct imsic_regs *regs;
-	struct imsic_data *data = imsic_hartid2data[target_hart];
-	int file = imsic_hartid2file[target_hart];
+	struct imsic_data *data;
+	struct sbi_scratch *scratch;
+	int file;
+
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
+		return;
 
+	data = imsic_get_hart_data_ptr(scratch);
+	file = imsic_get_hart_file(scratch);
 	if (!data || !data->targets_mmode)
 		return;
 
@@ -204,7 +236,7 @@ void imsic_local_irqchip_init(void)
 
 int imsic_warm_irqchip_init(void)
 {
-	struct imsic_data *imsic = imsic_hartid2data[current_hartid()];
+	struct imsic_data *imsic = imsic_get_data(current_hartid());
 
 	/* Sanity checks */
 	if (!imsic || !imsic->targets_mmode)
@@ -306,6 +338,20 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic)
 	if (!imsic->targets_mmode)
 		return SBI_EINVAL;
 
+	/* Allocate scratch space pointer */
+	if (!imsic_ptr_offset) {
+		imsic_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+		if (!imsic_ptr_offset)
+			return SBI_ENOMEM;
+	}
+
+	/* Allocate scratch space file */
+	if (!imsic_file_offset) {
+		imsic_file_offset = sbi_scratch_alloc_type_offset(long);
+		if (!imsic_file_offset)
+			return SBI_ENOMEM;
+	}
+
 	/* Setup external interrupt function for IMSIC */
 	sbi_irqchip_set_irqfn(imsic_external_irqfn);
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:44 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:44 +0530
Subject: [PATCH v2 13/18] lib: utils/fdt: Use heap in FDT domain parsing
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-14-apatel@ventanamicro.com>

Let's use heap allocation in FDT domain parsing instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/fdt/fdt_domain.c | 113 +++++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 42 deletions(-)

diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index bb6d17d..788683d 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -13,6 +13,7 @@
 #include <sbi/sbi_domain.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi_utils/fdt/fdt_domain.h>
 #include <sbi_utils/fdt/fdt_helper.h>
@@ -219,14 +220,13 @@ skip_device_disable:
 	fdt_nop_node(fdt, poffset);
 }
 
-#define FDT_DOMAIN_MAX_COUNT		8
 #define FDT_DOMAIN_REGION_MAX_COUNT	16
 
-static u32 fdt_domains_count;
-static struct sbi_domain fdt_domains[FDT_DOMAIN_MAX_COUNT];
-static struct sbi_hartmask fdt_masks[FDT_DOMAIN_MAX_COUNT];
-static struct sbi_domain_memregion
-	fdt_regions[FDT_DOMAIN_MAX_COUNT][FDT_DOMAIN_REGION_MAX_COUNT + 1];
+struct parse_region_data {
+	struct sbi_domain *dom;
+	u32 region_count;
+	u32 max_regions;
+};
 
 static int __fdt_parse_region(void *fdt, int domain_offset,
 			      int region_offset, u32 region_access,
@@ -236,7 +236,7 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
 	u32 val32;
 	u64 val64;
 	const u32 *val;
-	u32 *region_count = opaque;
+	struct parse_region_data *preg = opaque;
 	struct sbi_domain_memregion *region;
 
 	/*
@@ -252,9 +252,9 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
 		return SBI_EINVAL;
 
 	/* Find next region of the domain */
-	if (FDT_DOMAIN_REGION_MAX_COUNT <= *region_count)
-		return SBI_EINVAL;
-	region = &fdt_regions[fdt_domains_count][*region_count];
+	if (preg->max_regions <= preg->region_count)
+		return SBI_ENOSPC;
+	region = &preg->dom->regions[preg->region_count];
 
 	/* Read "base" DT property */
 	val = fdt_getprop(fdt, region_offset, "base", &len);
@@ -278,7 +278,7 @@ static int __fdt_parse_region(void *fdt, int domain_offset,
 	if (fdt_get_property(fdt, region_offset, "mmio", NULL))
 		region->flags |= SBI_DOMAIN_MEMREGION_MMIO;
 
-	(*region_count)++;
+	preg->region_count++;
 
 	return 0;
 }
@@ -291,16 +291,30 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 	struct sbi_domain *dom;
 	struct sbi_hartmask *mask;
 	struct sbi_hartmask assign_mask;
+	struct parse_region_data preg;
 	int *cold_domain_offset = opaque;
-	struct sbi_domain_memregion *reg, *regions;
-	int i, err, len, cpus_offset, cpu_offset, doffset;
-
-	/* Sanity check on maximum domains we can handle */
-	if (FDT_DOMAIN_MAX_COUNT <= fdt_domains_count)
-		return SBI_EINVAL;
-	dom = &fdt_domains[fdt_domains_count];
-	mask = &fdt_masks[fdt_domains_count];
-	regions = &fdt_regions[fdt_domains_count][0];
+	struct sbi_domain_memregion *reg;
+	int i, err = 0, len, cpus_offset, cpu_offset, doffset;
+
+	dom = sbi_zalloc(sizeof(*dom));
+	if (!dom)
+		return SBI_ENOMEM;
+
+	dom->regions = sbi_calloc(sizeof(*dom->regions),
+				  FDT_DOMAIN_REGION_MAX_COUNT + 1);
+	if (!dom->regions) {
+		err = SBI_ENOMEM;
+		goto fail_free_domain;
+	}
+	preg.dom = dom;
+	preg.region_count = 0;
+	preg.max_regions = FDT_DOMAIN_REGION_MAX_COUNT;
+
+	mask = sbi_zalloc(sizeof(*mask));
+	if (!mask) {
+		err = SBI_ENOMEM;
+		goto fail_free_regions;
+	}
 
 	/* Read DT node name */
 	strncpy(dom->name, fdt_get_name(fdt, domain_offset, NULL),
@@ -316,12 +330,14 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 		for (i = 0; i < len; i++) {
 			cpu_offset = fdt_node_offset_by_phandle(fdt,
 							fdt32_to_cpu(val[i]));
-			if (cpu_offset < 0)
-				return cpu_offset;
+			if (cpu_offset < 0) {
+				err = cpu_offset;
+				goto fail_free_all;
+			}
 
 			err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
 			if (err)
-				return err;
+				goto fail_free_all;
 
 			if (!fdt_node_is_enabled(fdt, cpu_offset))
 				continue;
@@ -331,14 +347,10 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 	}
 
 	/* Setup memregions from DT */
-	val32 = 0;
-	memset(regions, 0,
-		   sizeof(*regions) * (FDT_DOMAIN_REGION_MAX_COUNT + 1));
-	dom->regions = regions;
-	err = fdt_iterate_each_memregion(fdt, domain_offset, &val32,
+	err = fdt_iterate_each_memregion(fdt, domain_offset, &preg,
 					 __fdt_parse_region);
 	if (err)
-		return err;
+		goto fail_free_all;
 
 	/*
 	 * Copy over root domain memregions which don't allow
@@ -354,9 +366,11 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) ||
 		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
 			continue;
-		if (FDT_DOMAIN_REGION_MAX_COUNT <= val32)
-			return SBI_EINVAL;
-		memcpy(&regions[val32++], reg, sizeof(*reg));
+		if (preg.max_regions <= preg.region_count) {
+			err = SBI_EINVAL;
+			goto fail_free_all;
+		}
+		memcpy(&dom->regions[preg.region_count++], reg, sizeof(*reg));
 	}
 	dom->fw_region_inited = root.fw_region_inited;
 
@@ -427,8 +441,10 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 
 	/* Find /cpus DT node */
 	cpus_offset = fdt_path_offset(fdt, "/cpus");
-	if (cpus_offset < 0)
-		return cpus_offset;
+	if (cpus_offset < 0) {
+		err = cpus_offset;
+		goto fail_free_all;
+	}
 
 	/* HART to domain assignment mask based on CPU DT nodes */
 	sbi_hartmask_clear_all(&assign_mask);
@@ -444,22 +460,35 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 			continue;
 
 		val = fdt_getprop(fdt, cpu_offset, "opensbi-domain", &len);
-		if (!val || len < 4)
-			return SBI_EINVAL;
+		if (!val || len < 4) {
+			err = SBI_EINVAL;
+			goto fail_free_all;
+		}
 
 		doffset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*val));
-		if (doffset < 0)
-			return doffset;
+		if (doffset < 0) {
+			err = doffset;
+			goto fail_free_all;
+		}
 
 		if (doffset == domain_offset)
 			sbi_hartmask_set_hart(val32, &assign_mask);
 	}
 
-	/* Increment domains count */
-	fdt_domains_count++;
-
 	/* Register the domain */
-	return sbi_domain_register(dom, &assign_mask);
+	err = sbi_domain_register(dom, &assign_mask);
+	if (err)
+		goto fail_free_all;
+
+	return 0;
+
+fail_free_all:
+	sbi_free(mask);
+fail_free_regions:
+	sbi_free(dom->regions);
+fail_free_domain:
+	sbi_free(dom);
+	return err;
 }
 
 int fdt_domains_populate(void *fdt)
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:43 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:43 +0530
Subject: [PATCH v2 12/18] lib: utils/timer: Use heap in ACLINT MTIMER driver
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-13-apatel@ventanamicro.com>

Let's use heap allocation in ACLINT MTIMER driver instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/timer/fdt_timer_mtimer.c | 47 +++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c
index 5244f98..9eaa11d 100644
--- a/lib/utils/timer/fdt_timer_mtimer.c
+++ b/lib/utils/timer/fdt_timer_mtimer.c
@@ -9,44 +9,54 @@
 
 #include <libfdt.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_list.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/timer/fdt_timer.h>
 #include <sbi_utils/timer/aclint_mtimer.h>
 
-#define MTIMER_MAX_NR			16
-
 struct timer_mtimer_quirks {
 	unsigned int	mtime_offset;
 	bool		has_64bit_mmio;
 	bool		without_mtime;
 };
 
-static unsigned long mtimer_count = 0;
-static struct aclint_mtimer_data mtimer[MTIMER_MAX_NR];
+struct timer_mtimer_node {
+	struct sbi_dlist head;
+	struct aclint_mtimer_data data;
+};
+static SBI_LIST_HEAD(mtn_list);
+
 static struct aclint_mtimer_data *mt_reference = NULL;
 
 static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 				  const struct fdt_match *match)
 {
-	int i, rc;
+	int rc;
 	unsigned long addr[2], size[2];
+	struct timer_mtimer_node *mtn, *n;
 	struct aclint_mtimer_data *mt;
 
-	if (MTIMER_MAX_NR <= mtimer_count)
-		return SBI_ENOSPC;
-	mt = &mtimer[mtimer_count];
+	mtn = sbi_zalloc(sizeof(*mtn));
+	if (!mtn)
+		return SBI_ENOMEM;
+	mt = &mtn->data;
 
 	rc = fdt_parse_aclint_node(fdt, nodeoff, true,
 				   &addr[0], &size[0], &addr[1], &size[1],
 				   &mt->first_hartid, &mt->hart_count);
-	if (rc)
+	if (rc) {
+		sbi_free(mtn);
 		return rc;
+	}
 	mt->has_64bit_mmio = true;
 	mt->has_shared_mtime = false;
 
 	rc = fdt_parse_timebase_frequency(fdt, &mt->mtime_freq);
-	if (rc)
+	if (rc) {
+		sbi_free(mtn);
 		return rc;
+	}
 
 	if (match->data) { /* SiFive CLINT */
 		const struct timer_mtimer_quirks *quirks = match->data;
@@ -77,8 +87,8 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 	/* Check if MTIMER device has shared MTIME address */
 	if (mt->mtime_size) {
 		mt->has_shared_mtime = false;
-		for (i = 0; i < mtimer_count; i++) {
-			if (mtimer[i].mtime_addr == mt->mtime_addr) {
+		sbi_list_for_each_entry(n, &mtn_list, head) {
+			if (n->data.mtime_addr == mt->mtime_addr) {
 				mt->has_shared_mtime = true;
 				break;
 			}
@@ -90,8 +100,10 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 
 	/* Initialize the MTIMER device */
 	rc = aclint_mtimer_cold_init(mt, mt_reference);
-	if (rc)
+	if (rc) {
+		sbi_free(mtn);
 		return rc;
+	}
 
 	/*
 	 * Select first MTIMER device with no associated HARTs as our
@@ -106,16 +118,17 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 		 * Set reference for already propbed MTIMER devices
 		 * with non-shared MTIME
 		 */
-		for (i = 0; i < mtimer_count; i++)
-			if (!mtimer[i].has_shared_mtime)
-				aclint_mtimer_set_reference(&mtimer[i], mt);
+		sbi_list_for_each_entry(n, &mtn_list, head) {
+			if (!n->data.has_shared_mtime)
+				aclint_mtimer_set_reference(&n->data, mt);
+		}
 	}
 
 	/* Explicitly sync-up MTIMER devices not associated with any HARTs */
 	if (!mt->hart_count)
 		aclint_mtimer_sync(mt);
 
-	mtimer_count++;
+	sbi_list_add_tail(&mtn->head, &mtn_list);
 	return 0;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:41 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:41 +0530
Subject: [PATCH v2 10/18] lib: utils/ipi: Use heap in ACLINT MSWI driver
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-11-apatel@ventanamicro.com>

Let's use heap allocation in ACLINT MSWI driver instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/ipi/fdt_ipi_mswi.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/lib/utils/ipi/fdt_ipi_mswi.c b/lib/utils/ipi/fdt_ipi_mswi.c
index 4dc91f2..e3a6378 100644
--- a/lib/utils/ipi/fdt_ipi_mswi.c
+++ b/lib/utils/ipi/fdt_ipi_mswi.c
@@ -8,15 +8,11 @@
  */
 
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/ipi/fdt_ipi.h>
 #include <sbi_utils/ipi/aclint_mswi.h>
 
-#define MSWI_MAX_NR			16
-
-static unsigned long mswi_count = 0;
-static struct aclint_mswi_data mswi[MSWI_MAX_NR];
-
 static int ipi_mswi_cold_init(void *fdt, int nodeoff,
 			      const struct fdt_match *match)
 {
@@ -24,15 +20,17 @@ static int ipi_mswi_cold_init(void *fdt, int nodeoff,
 	unsigned long offset;
 	struct aclint_mswi_data *ms;
 
-	if (MSWI_MAX_NR <= mswi_count)
-		return SBI_ENOSPC;
-	ms = &mswi[mswi_count];
+	ms = sbi_zalloc(sizeof(*ms));
+	if (!ms)
+		return SBI_ENOMEM;
 
 	rc = fdt_parse_aclint_node(fdt, nodeoff, false,
 				   &ms->addr, &ms->size, NULL, NULL,
 				   &ms->first_hartid, &ms->hart_count);
-	if (rc)
+	if (rc) {
+		sbi_free(ms);
 		return rc;
+	}
 
 	if (match->data) {
 		/* Adjust MSWI address and size for CLINT device */
@@ -44,10 +42,11 @@ static int ipi_mswi_cold_init(void *fdt, int nodeoff,
 	}
 
 	rc = aclint_mswi_cold_init(ms);
-	if (rc)
+	if (rc) {
+		sbi_free(ms);
 		return rc;
+	}
 
-	mswi_count++;
 	return 0;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:42 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:42 +0530
Subject: [PATCH v2 11/18] lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-12-apatel@ventanamicro.com>

Let's use heap allocation in PLIC, APLIC, and IMSIC irqchip drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/irqchip/fdt_irqchip_aplic.c | 24 ++++++++++--------
 lib/utils/irqchip/fdt_irqchip_imsic.c | 28 +++++++++------------
 lib/utils/irqchip/fdt_irqchip_plic.c  | 36 ++++++++++++---------------
 3 files changed, 42 insertions(+), 46 deletions(-)

diff --git a/lib/utils/irqchip/fdt_irqchip_aplic.c b/lib/utils/irqchip/fdt_irqchip_aplic.c
index 965f023..583a3e3 100644
--- a/lib/utils/irqchip/fdt_irqchip_aplic.c
+++ b/lib/utils/irqchip/fdt_irqchip_aplic.c
@@ -11,15 +11,11 @@
 #include <libfdt.h>
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/aplic.h>
 
-#define APLIC_MAX_NR			16
-
-static unsigned long aplic_count = 0;
-static struct aplic_data aplic[APLIC_MAX_NR];
-
 static int irqchip_aplic_warm_init(void)
 {
 	/* Nothing to do here. */
@@ -32,15 +28,23 @@ static int irqchip_aplic_cold_init(void *fdt, int nodeoff,
 	int rc;
 	struct aplic_data *pd;
 
-	if (APLIC_MAX_NR <= aplic_count)
-		return SBI_ENOSPC;
-	pd = &aplic[aplic_count++];
+	pd = sbi_zalloc(sizeof(*pd));
+	if (!pd)
+		return SBI_ENOMEM;
 
 	rc = fdt_parse_aplic_node(fdt, nodeoff, pd);
 	if (rc)
-		return rc;
+		goto fail_free_data;
+
+	rc = aplic_cold_irqchip_init(pd);
+	if (rc)
+		goto fail_free_data;
+
+	return 0;
 
-	return aplic_cold_irqchip_init(pd);
+fail_free_data:
+	sbi_free(pd);
+	return rc;
 }
 
 static const struct fdt_match irqchip_aplic_match[] = {
diff --git a/lib/utils/irqchip/fdt_irqchip_imsic.c b/lib/utils/irqchip/fdt_irqchip_imsic.c
index 6020ac0..590b202 100644
--- a/lib/utils/irqchip/fdt_irqchip_imsic.c
+++ b/lib/utils/irqchip/fdt_irqchip_imsic.c
@@ -11,16 +11,12 @@
 #include <libfdt.h>
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/imsic.h>
 
-#define IMSIC_MAX_NR			16
-
-static unsigned long imsic_count = 0;
-static struct imsic_data imsic[IMSIC_MAX_NR];
-
 static int irqchip_imsic_update_hartid_table(void *fdt, int nodeoff,
 					     struct imsic_data *id)
 {
@@ -71,27 +67,27 @@ static int irqchip_imsic_cold_init(void *fdt, int nodeoff,
 	int rc;
 	struct imsic_data *id;
 
-	if (IMSIC_MAX_NR <= imsic_count)
-		return SBI_ENOSPC;
-	id = &imsic[imsic_count];
+	id = sbi_zalloc(sizeof(*id));
+	if (!id)
+		return SBI_ENOMEM;
 
 	rc = fdt_parse_imsic_node(fdt, nodeoff, id);
-	if (rc)
-		return rc;
-	if (!id->targets_mmode)
-		return 0;
+	if (rc || !id->targets_mmode)
+		goto fail_free_data;
 
 	rc = irqchip_imsic_update_hartid_table(fdt, nodeoff, id);
 	if (rc)
-		return rc;
+		goto fail_free_data;
 
 	rc = imsic_cold_irqchip_init(id);
 	if (rc)
-		return rc;
-
-	imsic_count++;
+		goto fail_free_data;
 
 	return 0;
+
+fail_free_data:
+	sbi_free(id);
+	return rc;
 }
 
 static const struct fdt_match irqchip_imsic_match[] = {
diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
index 1aadf91..d733284 100644
--- a/lib/utils/irqchip/fdt_irqchip_plic.c
+++ b/lib/utils/irqchip/fdt_irqchip_plic.c
@@ -11,18 +11,14 @@
 #include <sbi/riscv_asm.h>
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/plic.h>
 
-#define PLIC_MAX_NR			16
-
-static unsigned long plic_count = 0;
-static struct plic_data plic[PLIC_MAX_NR];
-
 static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
-static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2];
+static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
 
 void fdt_plic_priority_save(u8 *priority, u32 num)
 {
@@ -114,16 +110,16 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
 static int irqchip_plic_cold_init(void *fdt, int nodeoff,
 				  const struct fdt_match *match)
 {
-	int i, rc;
+	int rc;
 	struct plic_data *pd;
 
-	if (PLIC_MAX_NR <= plic_count)
-		return SBI_ENOSPC;
-	pd = &plic[plic_count++];
+	pd = sbi_zalloc(sizeof(*pd));
+	if (!pd)
+		return SBI_ENOMEM;
 
 	rc = fdt_parse_plic_node(fdt, nodeoff, pd);
 	if (rc)
-		return rc;
+		goto fail_free_data;
 
 	if (match->data) {
 		void (*plic_plat_init)(struct plic_data *) = match->data;
@@ -132,17 +128,17 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
 
 	rc = plic_cold_irqchip_init(pd);
 	if (rc)
-		return rc;
+		goto fail_free_data;
 
-	if (plic_count == 1) {
-		for (i = 0; i < SBI_HARTMASK_MAX_BITS; i++) {
-			plic_hartid2data[i] = NULL;
-			plic_hartid2context[i][0] = -1;
-			plic_hartid2context[i][1] = -1;
-		}
-	}
+	rc = irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
+	if (rc)
+		goto fail_free_data;
+
+	return 0;
 
-	return irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
+fail_free_data:
+	sbi_free(pd);
+	return rc;
 }
 
 #define THEAD_PLIC_CTRL_REG 0x1ffffc
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:47 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:47 +0530
Subject: [PATCH v2 16/18] lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-17-apatel@ventanamicro.com>

Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART PLIC pointer and PLIC context numbers.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/irqchip/fdt_irqchip_plic.c | 88 +++++++++++++++++++++-------
 1 file changed, 66 insertions(+), 22 deletions(-)

diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
index d733284..829c5ee 100644
--- a/lib/utils/irqchip/fdt_irqchip_plic.c
+++ b/lib/utils/irqchip/fdt_irqchip_plic.c
@@ -12,54 +12,77 @@
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_heap.h>
-#include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_scratch.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/plic.h>
 
-static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
-static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
+static unsigned long plic_ptr_offset;
+
+#define plic_get_hart_data_ptr(__scratch)				\
+	sbi_scratch_read_type((__scratch), void *, plic_ptr_offset)
+
+#define plic_set_hart_data_ptr(__scratch, __plic)			\
+	sbi_scratch_write_type((__scratch), void *, plic_ptr_offset, (__plic))
+
+static unsigned long plic_mcontext_offset;
+
+#define plic_get_hart_mcontext(__scratch)				\
+	(sbi_scratch_read_type((__scratch), long, plic_mcontext_offset) - 1)
+
+#define plic_set_hart_mcontext(__scratch, __mctx)			\
+	sbi_scratch_write_type((__scratch), long, plic_mcontext_offset, (__mctx) + 1)
+
+static unsigned long plic_scontext_offset;
+
+#define plic_get_hart_scontext(__scratch)				\
+	(sbi_scratch_read_type((__scratch), long, plic_scontext_offset) - 1)
+
+#define plic_set_hart_scontext(__scratch, __sctx)			\
+	sbi_scratch_write_type((__scratch), long, plic_scontext_offset, (__sctx) + 1)
 
 void fdt_plic_priority_save(u8 *priority, u32 num)
 {
-	struct plic_data *plic = plic_hartid2data[current_hartid()];
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
-	plic_priority_save(plic, priority, num);
+	plic_priority_save(plic_get_hart_data_ptr(scratch), priority, num);
 }
 
 void fdt_plic_priority_restore(const u8 *priority, u32 num)
 {
-	struct plic_data *plic = plic_hartid2data[current_hartid()];
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
-	plic_priority_restore(plic, priority, num);
+	plic_priority_restore(plic_get_hart_data_ptr(scratch), priority, num);
 }
 
 void fdt_plic_context_save(bool smode, u32 *enable, u32 *threshold, u32 num)
 {
-	u32 hartid = current_hartid();
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
-	plic_context_save(plic_hartid2data[hartid],
-			  plic_hartid2context[hartid][smode],
+	plic_context_save(plic_get_hart_data_ptr(scratch),
+			  smode ? plic_get_hart_scontext(scratch) :
+				  plic_get_hart_mcontext(scratch),
 			  enable, threshold, num);
 }
 
 void fdt_plic_context_restore(bool smode, const u32 *enable, u32 threshold,
 			      u32 num)
 {
-	u32 hartid = current_hartid();
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
-	plic_context_restore(plic_hartid2data[hartid],
-			     plic_hartid2context[hartid][smode],
+	plic_context_restore(plic_get_hart_data_ptr(scratch),
+			     smode ? plic_get_hart_scontext(scratch) :
+				     plic_get_hart_mcontext(scratch),
 			     enable, threshold, num);
 }
 
 static int irqchip_plic_warm_init(void)
 {
-	u32 hartid = current_hartid();
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 
-	return plic_warm_irqchip_init(plic_hartid2data[hartid],
-				      plic_hartid2context[hartid][0],
-				      plic_hartid2context[hartid][1]);
+	return plic_warm_irqchip_init(plic_get_hart_data_ptr(scratch),
+				      plic_get_hart_mcontext(scratch),
+				      plic_get_hart_scontext(scratch));
 }
 
 static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
@@ -67,6 +90,7 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
 {
 	const fdt32_t *val;
 	u32 phandle, hwirq, hartid;
+	struct sbi_scratch *scratch;
 	int i, err, count, cpu_offset, cpu_intc_offset;
 
 	val = fdt_getprop(fdt, nodeoff, "interrupts-extended", &count);
@@ -90,16 +114,17 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
 		if (err)
 			continue;
 
-		if (SBI_HARTMASK_MAX_BITS <= hartid)
+		scratch = sbi_hartid_to_scratch(hartid);
+		if (!scratch)
 			continue;
 
-		plic_hartid2data[hartid] = pd;
+		plic_set_hart_data_ptr(scratch, pd);
 		switch (hwirq) {
 		case IRQ_M_EXT:
-			plic_hartid2context[hartid][0] = i / 2;
+			plic_set_hart_mcontext(scratch, i / 2);
 			break;
 		case IRQ_S_EXT:
-			plic_hartid2context[hartid][1] = i / 2;
+			plic_set_hart_scontext(scratch, i / 2);
 			break;
 		}
 	}
@@ -113,6 +138,24 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
 	int rc;
 	struct plic_data *pd;
 
+	if (!plic_ptr_offset) {
+		plic_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+		if (!plic_ptr_offset)
+			return SBI_ENOMEM;
+	}
+
+	if (!plic_mcontext_offset) {
+		plic_mcontext_offset = sbi_scratch_alloc_type_offset(long);
+		if (!plic_mcontext_offset)
+			return SBI_ENOMEM;
+	}
+
+	if (!plic_scontext_offset) {
+		plic_scontext_offset = sbi_scratch_alloc_type_offset(long);
+		if (!plic_scontext_offset)
+			return SBI_ENOMEM;
+	}
+
 	pd = sbi_zalloc(sizeof(*pd));
 	if (!pd)
 		return SBI_ENOMEM;
@@ -150,7 +193,8 @@ static void thead_plic_plat_init(struct plic_data *pd)
 
 void thead_plic_restore(void)
 {
-	struct plic_data *plic = plic_hartid2data[current_hartid()];
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct plic_data *plic = plic_get_hart_data_ptr(scratch);
 
 	thead_plic_plat_init(plic);
 }
-- 
2.34.1



From apatel at ventanamicro.com  Mon Jun  5 04:37:45 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon,  5 Jun 2023 17:07:45 +0530
Subject: [PATCH v2 14/18] lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <20230605113749.230696-15-apatel@ventanamicro.com>

Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART MSWI pointer.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 lib/utils/ipi/aclint_mswi.c | 43 ++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/lib/utils/ipi/aclint_mswi.c b/lib/utils/ipi/aclint_mswi.c
index ac8570b..f47b3bc 100644
--- a/lib/utils/ipi/aclint_mswi.c
+++ b/lib/utils/ipi/aclint_mswi.c
@@ -12,21 +12,30 @@
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_domain.h>
 #include <sbi/sbi_error.h>
-#include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_ipi.h>
+#include <sbi/sbi_scratch.h>
 #include <sbi/sbi_timer.h>
 #include <sbi_utils/ipi/aclint_mswi.h>
 
-static struct aclint_mswi_data *mswi_hartid2data[SBI_HARTMASK_MAX_BITS];
+static unsigned long mswi_ptr_offset;
+
+#define mswi_get_hart_data_ptr(__scratch)				\
+	sbi_scratch_read_type((__scratch), void *, mswi_ptr_offset)
+
+#define mswi_set_hart_data_ptr(__scratch, __mswi)			\
+	sbi_scratch_write_type((__scratch), void *, mswi_ptr_offset, (__mswi))
 
 static void mswi_ipi_send(u32 target_hart)
 {
 	u32 *msip;
+	struct sbi_scratch *scratch;
 	struct aclint_mswi_data *mswi;
 
-	if (SBI_HARTMASK_MAX_BITS <= target_hart)
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
 		return;
-	mswi = mswi_hartid2data[target_hart];
+
+	mswi = mswi_get_hart_data_ptr(scratch);
 	if (!mswi)
 		return;
 
@@ -38,11 +47,14 @@ static void mswi_ipi_send(u32 target_hart)
 static void mswi_ipi_clear(u32 target_hart)
 {
 	u32 *msip;
+	struct sbi_scratch *scratch;
 	struct aclint_mswi_data *mswi;
 
-	if (SBI_HARTMASK_MAX_BITS <= target_hart)
+	scratch = sbi_hartid_to_scratch(target_hart);
+	if (!scratch)
 		return;
-	mswi = mswi_hartid2data[target_hart];
+
+	mswi = mswi_get_hart_data_ptr(scratch);
 	if (!mswi)
 		return;
 
@@ -69,19 +81,30 @@ int aclint_mswi_cold_init(struct aclint_mswi_data *mswi)
 {
 	u32 i;
 	int rc;
+	struct sbi_scratch *scratch;
 	unsigned long pos, region_size;
 	struct sbi_domain_memregion reg;
 
 	/* Sanity checks */
 	if (!mswi || (mswi->addr & (ACLINT_MSWI_ALIGN - 1)) ||
 	    (mswi->size < (mswi->hart_count * sizeof(u32))) ||
-	    (mswi->first_hartid + mswi->hart_count > SBI_HARTMASK_MAX_BITS) ||
 	    (!mswi->hart_count || mswi->hart_count > ACLINT_MSWI_MAX_HARTS))
 		return SBI_EINVAL;
 
-	/* Update MSWI hartid table */
-	for (i = 0; i < mswi->hart_count; i++)
-		mswi_hartid2data[mswi->first_hartid + i] = mswi;
+	/* Allocate scratch space pointer */
+	if (!mswi_ptr_offset) {
+		mswi_ptr_offset = sbi_scratch_alloc_type_offset(void *);
+		if (!mswi_ptr_offset)
+			return SBI_ENOMEM;
+	}
+
+	/* Update MSWI pointer in scratch space */
+	for (i = 0; i < mswi->hart_count; i++) {
+		scratch = sbi_hartid_to_scratch(mswi->first_hartid + i);
+		if (!scratch)
+			return SBI_ENOENT;
+		mswi_set_hart_data_ptr(scratch, mswi);
+	}
 
 	/* Add MSWI regions to the root domain */
 	for (pos = 0; pos < mswi->size; pos += ACLINT_MSWI_ALIGN) {
-- 
2.34.1



From wxjstz at 126.com  Mon Jun  5 23:32:47 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 14:32:47 +0800
Subject: [PATCH] lib: sbi: Fix timing of clearing tbuf
Message-ID: <20230606063247.1174503-1-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..c092934 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -17,8 +17,8 @@
 #define CONSOLE_TBUF_MAX 256
 
 static const struct sbi_console_device *console_dev = NULL;
+static bool use_tbuf;
 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)
@@ -134,6 +134,12 @@ static void printc(char **out, u32 *out_len, char ch)
 		return;
 	}
 
+	if (use_tbuf && (*out_len == 0)) {
+		nputs_all(console_tbuf, CONSOLE_TBUF_MAX);
+		*out = console_tbuf;
+		*out_len = CONSOLE_TBUF_MAX;
+	}
+
 	/*
 	 * The *printf entry point functions have enforced that (*out) can
 	 * only be null when out_len is non-null and its value is zero.
@@ -238,7 +244,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	int width, flags, pc = 0;
 	char scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	u32 console_tbuf_len;
 	unsigned long long tmp;
 
 	/*
@@ -246,6 +252,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * print() is always called with console_out_lock held
 	 * when out == NULL.
 	 */
+	use_tbuf = (!out) ? true : false;
 	if (use_tbuf) {
 		console_tbuf_len = CONSOLE_TBUF_MAX;
 		tout = console_tbuf;
@@ -254,12 +261,6 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	}
 
 	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;
-- 
2.39.2



From jrtc27 at jrtc27.com  Mon Jun  5 23:42:16 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Tue, 6 Jun 2023 07:42:16 +0100
Subject: [PATCH] lib: sbi: Fix timing of clearing tbuf
In-Reply-To: <20230606063247.1174503-1-wxjstz@126.com>
References: <20230606063247.1174503-1-wxjstz@126.com>
Message-ID: <F5CF4FE2-CC5B-419A-B3F0-576FC4BC4FE3@jrtc27.com>

On 6 Jun 2023, at 07:32, Xiang W <wxjstz at 126.com> wrote:
> 
> A single scan of the format char may add multiple characters to the
> tbuf, causing a buffer overflow. You should check if tbuf is full in
> printc so that it does not cause a buffer overflow.
> 
> Signed-off-by: Xiang W <wxjstz at 126.com>
> ---
> lib/sbi/sbi_console.c | 17 +++++++++--------
> 1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> index 168dffd..c092934 100644
> --- a/lib/sbi/sbi_console.c
> +++ b/lib/sbi/sbi_console.c
> @@ -17,8 +17,8 @@
> #define CONSOLE_TBUF_MAX 256
> 
> static const struct sbi_console_device *console_dev = NULL;
> +static bool use_tbuf;
> 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)
> @@ -134,6 +134,12 @@ static void printc(char **out, u32 *out_len, char ch)
> return;
> }
> 
> + if (use_tbuf && (*out_len == 0)) {

Using a global variable to pass data into a function sounds dodgy.

Jess

> + nputs_all(console_tbuf, CONSOLE_TBUF_MAX);
> + *out = console_tbuf;
> + *out_len = CONSOLE_TBUF_MAX;
> + }
> +
> /*
> * The *printf entry point functions have enforced that (*out) can
> * only be null when out_len is non-null and its value is zero.
> @@ -238,7 +244,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> {
> int width, flags, pc = 0;
> char scr[2], *tout;
> - bool use_tbuf = (!out) ? true : false;
> + u32 console_tbuf_len;
> unsigned long long tmp;
> 
> /*
> @@ -246,6 +252,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> * print() is always called with console_out_lock held
> * when out == NULL.
> */
> + use_tbuf = (!out) ? true : false;
> if (use_tbuf) {
> console_tbuf_len = CONSOLE_TBUF_MAX;
> tout = console_tbuf;
> @@ -254,12 +261,6 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> }
> 
> 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;
> -- 
> 2.39.2
> 
> 
> -- 
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi



From wxjstz at 126.com  Tue Jun  6 00:12:44 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue, 06 Jun 2023 15:12:44 +0800
Subject: [PATCH] lib: sbi: Fix timing of clearing tbuf
In-Reply-To: <F5CF4FE2-CC5B-419A-B3F0-576FC4BC4FE3@jrtc27.com>
References: <20230606063247.1174503-1-wxjstz@126.com>
	 <F5CF4FE2-CC5B-419A-B3F0-576FC4BC4FE3@jrtc27.com>
Message-ID: <4f8277f34c63178aaefd3991d5afeb6d4c0a25ce.camel@126.com>

? 2023-06-06???? 07:42 +0100?Jessica Clarke???
> On 6 Jun 2023, at 07:32, Xiang W <wxjstz at 126.com> wrote:
> > 
> > A single scan of the format char may add multiple characters to the
> > tbuf, causing a buffer overflow. You should check if tbuf is full in
> > printc so that it does not cause a buffer overflow.
> > 
> > Signed-off-by: Xiang W <wxjstz at 126.com>
> > ---
> > lib/sbi/sbi_console.c | 17 +++++++++--------
> > 1 file changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> > index 168dffd..c092934 100644
> > --- a/lib/sbi/sbi_console.c
> > +++ b/lib/sbi/sbi_console.c
> > @@ -17,8 +17,8 @@
> > #define CONSOLE_TBUF_MAX 256
> > 
> > static const struct sbi_console_device *console_dev = NULL;
> > +static bool use_tbuf;
> > 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)
> > @@ -134,6 +134,12 @@ static void printc(char **out, u32 *out_len, char ch)
> > return;
> > }
> > 
> > + if (use_tbuf && (*out_len == 0)) {
> 
> Using a global variable to pass data into a function sounds dodgy.

You reminded well. When sbi_sprintf and sbi_printf are called at the
same time, the value of use_tbuf is broken, I will modify this patch
and re-post it.

Thank,
Xiang
> 
> Jess
> 
> > + nputs_all(console_tbuf, CONSOLE_TBUF_MAX);
> > + *out = console_tbuf;
> > + *out_len = CONSOLE_TBUF_MAX;
> > + }
> > +
> > /*
> > * The *printf entry point functions have enforced that (*out) can
> > * only be null when out_len is non-null and its value is zero.
> > @@ -238,7 +244,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> > {
> > int width, flags, pc = 0;
> > char scr[2], *tout;
> > - bool use_tbuf = (!out) ? true : false;
> > + u32 console_tbuf_len;
> > unsigned long long tmp;
> > 
> > /*
> > @@ -246,6 +252,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> > * print() is always called with console_out_lock held
> > * when out == NULL.
> > */
> > + use_tbuf = (!out) ? true : false;
> > if (use_tbuf) {
> > console_tbuf_len = CONSOLE_TBUF_MAX;
> > tout = console_tbuf;
> > @@ -254,12 +261,6 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> > }
> > 
> > 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;
> > -- 
> > 2.39.2
> > 
> > 
> > -- 
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi



From wxjstz at 126.com  Tue Jun  6 03:30:22 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:22 +0800
Subject: [PATCH v2 00/12] Improve sbi_console
Message-ID: <20230606103034.1218221-1-wxjstz@126.com>

v2 changes:
- add patch 10-12

Xiang W (12):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf

 lib/sbi/sbi_console.c | 408 +++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 204 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:29 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:29 +0800
Subject: [PATCH v2 07/12] lib: sbi: print add 'o' type
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:25 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:25 +0800
Subject: [PATCH v2 03/12] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:27 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:27 +0800
Subject: [PATCH v2 05/12] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:03 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:03 +0800
Subject: [PATCH v2 03/12] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:00 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:00 +0800
Subject: [PATCH v2 00/12] Improve sbi_console
Message-ID: <20230606103112.1218382-1-wxjstz@126.com>

v2 changes:
- add patch 10-12

Xiang W (12):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf

 lib/sbi/sbi_console.c | 408 +++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 204 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:07 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:07 +0800
Subject: [PATCH v2 07/12] lib: sbi: print add 'o' type
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:06 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:06 +0800
Subject: [PATCH v2 06/12] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:26 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:26 +0800
Subject: [PATCH v2 04/12] lib: sbi: Add '+' flags for print
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:23 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:23 +0800
Subject: [PATCH v2 01/12] lib: sbi: Fix missing contine in print
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-2-wxjstz@126.com>

Missing continue after print %lu %ld %lx ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:28 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:28 +0800
Subject: [PATCH v2 06/12] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:30 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:30 +0800
Subject: [PATCH v2 08/12] lib: sbi: Fix printi
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:10 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:10 +0800
Subject: [PATCH v2 10/12] lib: sbi: sbi_console.c code re-layout
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-11-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:31 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:31 +0800
Subject: [PATCH v2 09/12] lib: sbi: Simplify prints
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-10-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:32:35 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:32:35 +0800
Subject: [PATCH v2 11/12] lib: sbi: Add print_info for sbi_console.c
Message-ID: <20230606103235.1218744-1-wxjstz@126.com>

Create a structure print_info for print, this structure simplifies
parameter passing.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 235 +++++++++++++++++++++---------------------
 1 file changed, 119 insertions(+), 116 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index af93f51..922de20 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -27,11 +27,22 @@
 
 typedef __builtin_va_list va_list;
 
+struct print_info {
+	char *out;
+	int len;
+	int pos;
+	int pc;
+	int flags;
+	int width;
+	int wcnt;
+	char type;
+};
+
 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)
 {
 	if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
@@ -128,70 +139,57 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-static void printc(char **out, u32 *out_len, char ch)
+static void printc(struct print_info *info, char ch)
 {
-	if (!out) {
+	if (info->out == NULL) {
 		sbi_putc(ch);
-		return;
-	}
-
-	/*
-	 * The *printf entry point functions have enforced that (*out) can
-	 * only be null when out_len is non-null and its value is zero.
-	 */
-	if (!out_len || *out_len > 1) {
-		*(*out)++ = ch;
-		**out = '\0';
+		info->pc++;
+	} else {
+		if (info->len == 0) {
+			info->out[info->pos++] = ch;
+			info->out[info->pos] = '\0';
+			info->pc++;
+		} else if (info->len - info->pos >= 2) {
+			info->out[info->pos++] = ch;
+			info->out[info->pos] = '\0';
+			info->pc++;
+		}
 	}
-
-	if (out_len && *out_len > 0)
-		--(*out_len);
 }
 
-static int prints(char **out, u32 *out_len, const char *string, int width,
-		  int flags)
+static void prints(struct print_info *info, const char *string)
 {
-	int pc = 0;
-	width -= sbi_strlen(string);
-	if (!(flags & PAD_RIGHT)) {
-		for (; width > 0; --width) {
-			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
-			++pc;
-		}
-	}
-	for (; *string; ++string) {
-		printc(out, out_len, *string);
-		++pc;
-	}
-	for (; width > 0; --width) {
-		printc(out, out_len, ' ');
-		++pc;
+	info->wcnt += sbi_strlen(string);
+	if (!(info->flags & PAD_RIGHT)) {
+		for (; info->wcnt < info->width; info->wcnt++)
+			printc(info, info->flags & PAD_ZERO ? '0' : ' ');
 	}
-
-	return pc;
+	for (; *string; ++string)
+		printc(info, *string);
+	for (; info->wcnt < info->width; info->wcnt++)
+		printc(info, ' ');
 }
 
-static int printi(char **out, u32 *out_len, long long i,
-		  int width, int flags, int type)
+static void printi(struct print_info *info, long long i)
 {
-	int pc = 0;
 	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
 	unsigned long long u, b, t;
 
 	b = 10;
 	letbase = 'a';
-	if (type == 'o')
+	if (info->type == 'o')
 		b = 8;
-	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+	else if (info->type == 'x' || info->type == 'X'
+			 || info->type == 'p' || info->type == 'P') {
 		b = 16;
 		letbase &= ~0x20;
-		letbase |= type & 0x20;
+		letbase |= info->type & 0x20;
 	}
 
 	u = i;
 	sign = 0;
-	if (type == 'i' || type == 'd') {
-		if ((flags & PAD_SIGN) && i > 0)
+	if (info->type == 'i' || info->type == 'd') {
+		if ((info->flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
 			sign = '-';
@@ -214,26 +212,23 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ZERO) {
+	if (info->flags & PAD_ZERO) {
 		if (sign) {
-			printc(out, out_len, sign);
-			++pc;
-			--width;
+			printc(info, sign);
+			++info->wcnt;
 		}
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16 || b == 8) {
-				printc(out, out_len, '0');
-				++pc;
-				--width;
+				printc(info, '0');
+				++info->wcnt;
 			}
 			if (b == 16) {
-				printc(out, out_len, 'x' - 'a' + letbase);
-				++pc;
-				--width;
+				printc(info, 'x' - 'a' + letbase);
+				++info->wcnt;
 			}
 		}
 	} else {
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16)
 				*--s = 'x' - 'a' + letbase;
 			if (b == 16 || b == 8)
@@ -243,15 +238,16 @@ static int printi(char **out, u32 *out_len, long long i,
 			*--s = sign;
 	}
 
-	return pc + prints(out, out_len, s, width, flags);
+	prints(info, s);
 }
 
-static int print(char **out, u32 *out_len, const char *format, va_list args)
+static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
-	int width, flags, pc = 0;
-	char type, scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	char scr[2];
+	bool use_tbuf = (!info->out) ? true : false;
+	info->pos = 0;
+	info->pc = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -259,17 +255,14 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
-		console_tbuf_len = CONSOLE_TBUF_MAX;
-		tout = console_tbuf;
-		out = &tout;
-		out_len = &console_tbuf_len;
+		info->out = console_tbuf;
+		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	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 (use_tbuf && info->len - info->pos < 2) {
+			nputs_all(info->out, info->pos);
+			info->pos = 0;
 		}
 
 		if (*format == '%') {
@@ -279,21 +272,21 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			flags = 0;
+			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
 				case '-':
-					flags |= PAD_RIGHT;
+					info->flags |= PAD_RIGHT;
 					break;
 				case '+':
-					flags |= PAD_SIGN;
+					info->flags |= PAD_SIGN;
 					break;
 				case '#':
-					flags |= PAD_ALTERNATE;
+					info->flags |= PAD_ALTERNATE;
 					break;
 				case '0':
-					flags |= PAD_ZERO;
+					info->flags |= PAD_ZERO;
 					break;
 				case ' ':
 				case '\'':
@@ -306,153 +299,163 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
-			if (flags & PAD_RIGHT)
-				flags &= ~PAD_ZERO;
+			if (info->flags & PAD_RIGHT)
+				info->flags &= ~PAD_ZERO;
 			/* Get width */
-			width = 0;
+			info->wcnt = 0;
+			info->width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-				width *= 10;
-				width += *format - '0';
+				info->width *= 10;
+				info->width += *format - '0';
 			}
 			if (*format == 's') {
 				char *s = va_arg(args, char *);
-				pc += prints(out, out_len, s ? s : "(null)",
-					     width, flags);
+				info->type = *format;
+				prints(info, s ? s : "(null)");
 				continue;
 			}
 			if ((*format == 'd') || (*format == 'i')) {
-				pc += printi(out, out_len, va_arg(args, int),
-					     width, flags, *format);
+				info->type = *format;
+				printi(info, va_arg(args, int));
 				continue;
 			}
 			if ((*format == 'u') || (*format == 'o')
 					 || (*format == 'x') || (*format == 'X')) {
-				pc += printi(out, out_len, va_arg(args, unsigned int),
-					     width, flags, *format);
+				info->type = *format;
+				printi(info, va_arg(args, unsigned int));
 				continue;
 			}
 			if ((*format == 'p') || (*format == 'P')) {
-				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
-					     width, flags, *format);
+				info->type = *format;
+				printi(info, (uintptr_t)va_arg(args, void*));
 				continue;
 			}
 			if (*format == 'l') {
-				type = 'i';
+				info->type = 'i';
 				if (format[1] == 'l') {
 					++format;
 					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
-						type = *format;
+						info->type = *format;
 					}
-					pc += printi(out, out_len, va_arg(args, long long),
-						width, flags, type);
+					printi(info, va_arg(args, long long));
 					continue;
 				}
 				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-					type = *format;
+					info->type = *format;
 				}
-				if ((type == 'd') || (type == 'i'))
-					pc += printi(out, out_len, va_arg(args, long),
-					     width, flags, type);
+				if ((info->type == 'd') || (info->type == 'i'))
+					printi(info, va_arg(args, long));
 				else
-					pc += printi(out, out_len, va_arg(args, unsigned long),
-					     width, flags, type);
+					printi(info, va_arg(args, unsigned long));
 				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
 				scr[0] = va_arg(args, int);
 				scr[1] = '\0';
-				pc += prints(out, out_len, scr, width, flags);
+				prints(info, scr);
 				continue;
 			}
 		} else {
 literal:
-			printc(out, out_len, *format);
-			++pc;
+			printc(info, *format);
 		}
 	}
 
-	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
-		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
-
-	return pc;
+	if (use_tbuf && info->pos > 0)
+		nputs_all(info->out, info->pos);
 }
 
 int sbi_sprintf(char *out, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = 0;
+
 
 	if (unlikely(!out))
 		sbi_panic("sbi_sprintf called with NULL output string\n");
 
 	va_start(args, format);
-	retval = print(&out, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = out_sz;
+
 
 	if (unlikely(!out && out_sz != 0))
 		sbi_panic("sbi_snprintf called with NULL output string and "
 			  "output size is not zero\n");
 
 	va_start(args, format);
-	retval = print(&out, &out_sz, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_printf(const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	retval = print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_dprintf(const char *format, ...)
 {
 	va_list args;
-	int retval = 0;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	va_start(args, format);
 	if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) {
 		spin_lock(&console_out_lock);
-		retval = print(NULL, NULL, format, args);
+		print(&info, format, args);
 		spin_unlock(&console_out_lock);
 	}
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 void sbi_panic(const char *format, ...)
 {
 	va_list args;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:32 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:32 +0800
Subject: [PATCH v2 10/12] lib: sbi: sbi_console.c code re-layout
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-11-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From apatel at ventanamicro.com  Tue Jun  6 03:33:43 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 6 Jun 2023 16:03:43 +0530
Subject: [PATCH v2 00/18] Introduce and use simple heap allocator
In-Reply-To: <20230605113749.230696-1-apatel@ventanamicro.com>
References: <20230605113749.230696-1-apatel@ventanamicro.com>
Message-ID: <CAK9=C2WK+xUjN7nGEoOC_vJKXACTsdCUHP6oGeHOyHyxcpWfng@mail.gmail.com>

On Mon, Jun 5, 2023 at 5:07?PM Anup Patel <apatel at ventanamicro.com> wrote:
>
> Currently, we use global variables instead of explicitly allocating
> memory in different parts of OpenSBI. This leads to a bloated BSS
> section in the firmware binaries and this will continue to grow as
> more drivers (and frameworks) with global variables are added.
>
> To improve memory utilizaiton in OpenSBI:
> 1) We introduce a simple heap allocator which based on linked list.
>    This is a reasonable heap implementation to start with because
>    heap allocation and free-up won't be in hot path.
> 2) Use a combination of heap allocations and scratch space allocations
>    to improve the reduce the BSS memory foot-print.
>
> As a by-product, this series also redunces global arrays indexed by hartid
> which is preparatory work for the upcoming full sparse hartid support.
>
> These patches can also be found in simple_heap_v2 branch at:
> https://github.com/avpatel/opensbi.git
>
> Chagnes since v1:
>  - Addressed Drew's comments in PATCH2, PATCH6, PATCH10, PATCH12, and
>    PATCH15
>  - New PATCH which adds helper macros in sbi_scratch.h to access
>    data type from scratch space.
>
> Anup Patel (18):
>   include: sbi_scratch: Add helper macros to access data type
>   platform: Allow platforms to specify heap size
>   lib: sbi: Introduce simple heap allocator
>   lib: sbi: Print scratch size and usage at boot time
>   lib: sbi_pmu: Use heap for per-HART PMU state
>   lib: sbi: Use heap for root domain creation
>   lib: sbi: Use scratch space to save per-HART domain pointer
>   lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
>   lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
>   lib: utils/ipi: Use heap in ACLINT MSWI driver
>   lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
>   lib: utils/timer: Use heap in ACLINT MTIMER driver
>   lib: utils/fdt: Use heap in FDT domain parsing
>   lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
>   lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
>   lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
>   lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
>   lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer

Applied this series to the riscv/opensbi repo.

Regards,
Anup

>
>  firmware/fw_base.S                    |  15 ++
>  include/sbi/sbi_domain.h              |   6 +-
>  include/sbi/sbi_heap.h                |  44 ++++++
>  include/sbi/sbi_platform.h            |  18 ++-
>  include/sbi/sbi_scratch.h             |  48 ++++--
>  lib/sbi/objects.mk                    |   1 +
>  lib/sbi/sbi_domain.c                  |  84 ++++++++--
>  lib/sbi/sbi_heap.c                    | 206 ++++++++++++++++++++++++
>  lib/sbi/sbi_init.c                    |  20 +++
>  lib/sbi/sbi_pmu.c                     | 215 +++++++++++++++-----------
>  lib/sbi/sbi_scratch.c                 |  11 ++
>  lib/utils/fdt/fdt_domain.c            | 113 +++++++++-----
>  lib/utils/gpio/fdt_gpio_sifive.c      |  21 ++-
>  lib/utils/gpio/fdt_gpio_starfive.c    |  20 +--
>  lib/utils/i2c/fdt_i2c_dw.c            |  24 ++-
>  lib/utils/i2c/fdt_i2c_sifive.c        |  23 ++-
>  lib/utils/ipi/aclint_mswi.c           |  43 ++++--
>  lib/utils/ipi/fdt_ipi_mswi.c          |  21 ++-
>  lib/utils/irqchip/fdt_irqchip_aplic.c |  24 +--
>  lib/utils/irqchip/fdt_irqchip_imsic.c |  35 ++---
>  lib/utils/irqchip/fdt_irqchip_plic.c  | 118 +++++++++-----
>  lib/utils/irqchip/imsic.c             |  76 +++++++--
>  lib/utils/timer/aclint_mtimer.c       |  76 +++++++--
>  lib/utils/timer/fdt_timer_mtimer.c    |  47 ++++--
>  platform/fpga/ariane/platform.c       |   1 +
>  platform/fpga/openpiton/platform.c    |   2 +
>  platform/generic/platform.c           |   3 +-
>  platform/kendryte/k210/platform.c     |   2 +
>  platform/nuclei/ux600/platform.c      |   2 +
>  platform/template/platform.c          |   1 +
>  30 files changed, 971 insertions(+), 349 deletions(-)
>  create mode 100644 include/sbi/sbi_heap.h
>  create mode 100644 lib/sbi/sbi_heap.c
>
> --
> 2.34.1
>


From wxjstz at 126.com  Tue Jun  6 03:32:48 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:32:48 +0800
Subject: [PATCH v2 12/12] lib: sbi: Fix timing of clearing tbuf
Message-ID: <20230606103248.1218864-1-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 922de20..d4e2651 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -18,6 +18,8 @@
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
 #define PAD_SIGN 8
+#define USED_TBUF (1 << (8 * sizeof(int) - 1))
+
 #define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
@@ -155,6 +157,11 @@ static void printc(struct print_info *info, char ch)
 			info->pc++;
 		}
 	}
+
+	if ((info->flags & USED_TBUF) && info->len - info->pos < 2) {
+		nputs_all(info->out, info->pos);
+		info->pos = 0;
+	}
 }
 
 static void prints(struct print_info *info, const char *string)
@@ -248,6 +255,7 @@ static void print(struct print_info *info, const char *format, va_list args)
 	bool use_tbuf = (!info->out) ? true : false;
 	info->pos = 0;
 	info->pc = 0;
+	info->flags = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -255,16 +263,12 @@ static void print(struct print_info *info, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
+		info->flags |= USED_TBUF;
 		info->out = console_tbuf;
 		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	for (; *format != 0; ++format) {
-		if (use_tbuf && info->len - info->pos < 2) {
-			nputs_all(info->out, info->pos);
-			info->pos = 0;
-		}
-
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -272,7 +276,7 @@ static void print(struct print_info *info, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			info->flags = 0;
+			info->flags &= USED_TBUF;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:01 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:01 +0800
Subject: [PATCH v2 01/12] lib: sbi: Fix missing contine in print
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-2-wxjstz@126.com>

Missing continue after print %lu %ld %lx ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:02 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:02 +0800
Subject: [PATCH v2 02/12] lib: sbi: Fix how print gets flags
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:08 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:08 +0800
Subject: [PATCH v2 08/12] lib: sbi: Fix printi
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:30:24 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:30:24 +0800
Subject: [PATCH v2 02/12] lib: sbi: Fix how print gets flags
In-Reply-To: <20230606103034.1218221-1-wxjstz@126.com>
References: <20230606103034.1218221-1-wxjstz@126.com>
Message-ID: <20230606103034.1218221-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:04 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:04 +0800
Subject: [PATCH v2 04/12] lib: sbi: Add '+' flags for print
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:05 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:05 +0800
Subject: [PATCH v2 05/12] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 03:31:09 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 18:31:09 +0800
Subject: [PATCH v2 09/12] lib: sbi: Simplify prints
In-Reply-To: <20230606103112.1218382-1-wxjstz@126.com>
References: <20230606103112.1218382-1-wxjstz@126.com>
Message-ID: <20230606103112.1218382-10-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:33 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:33 +0800
Subject: [PATCH v3 00/12] Improve sbi_console
Message-ID: <20230606132445.1239808-1-wxjstz@126.com>

v3 changes:
- PATCH11: Simplify get info->type
- PATCH12: Change the way to keep USED_TBUF by and to reset it by use_tbuf

v2 changes:
- add patch 10-12

Xiang W (12):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf

 lib/sbi/sbi_console.c | 405 +++++++++++++++++++++---------------------
 1 file changed, 201 insertions(+), 204 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:34 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:34 +0800
Subject: [PATCH v3 01/12] lib: sbi: Fix missing contine in print
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-2-wxjstz@126.com>

Missing continue after print %lu %ld %lx ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:37 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:37 +0800
Subject: [PATCH v3 04/12] lib: sbi: Add '+' flags for print
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:40 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:40 +0800
Subject: [PATCH v3 07/12] lib: sbi: print add 'o' type
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:41 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:41 +0800
Subject: [PATCH v3 08/12] lib: sbi: Fix printi
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:39 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:39 +0800
Subject: [PATCH v3 06/12] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:35 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:35 +0800
Subject: [PATCH v3 02/12] lib: sbi: Fix how print gets flags
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:38 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:38 +0800
Subject: [PATCH v3 05/12] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:24:36 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:24:36 +0800
Subject: [PATCH v3 03/12] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230606132445.1239808-1-wxjstz@126.com>
References: <20230606132445.1239808-1-wxjstz@126.com>
Message-ID: <20230606132445.1239808-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:29:12 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:29:12 +0800
Subject: [PATCH v3 10/12] lib: sbi: sbi_console.c code re-layout
Message-ID: <20230606132912.1240682-1-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:29:00 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:29:00 +0800
Subject: [PATCH v3 09/12] lib: sbi: Simplify prints
Message-ID: <20230606132900.1240578-1-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:29:29 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:29:29 +0800
Subject: [PATCH v3 11/12] lib: sbi: Add print_info for sbi_console.c
Message-ID: <20230606132930.1240817-1-wxjstz@126.com>

Create a structure print_info for print, this structure simplifies
parameter passing.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 232 +++++++++++++++++++++---------------------
 1 file changed, 116 insertions(+), 116 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index af93f51..7608bbd 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -27,11 +27,22 @@
 
 typedef __builtin_va_list va_list;
 
+struct print_info {
+	char *out;
+	int len;
+	int pos;
+	int pc;
+	int flags;
+	int width;
+	int wcnt;
+	char type;
+};
+
 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)
 {
 	if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
@@ -128,70 +139,57 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-static void printc(char **out, u32 *out_len, char ch)
+static void printc(struct print_info *info, char ch)
 {
-	if (!out) {
+	if (info->out == NULL) {
 		sbi_putc(ch);
-		return;
-	}
-
-	/*
-	 * The *printf entry point functions have enforced that (*out) can
-	 * only be null when out_len is non-null and its value is zero.
-	 */
-	if (!out_len || *out_len > 1) {
-		*(*out)++ = ch;
-		**out = '\0';
+		info->pc++;
+	} else {
+		if (info->len == 0) {
+			info->out[info->pos++] = ch;
+			info->out[info->pos] = '\0';
+			info->pc++;
+		} else if (info->len - info->pos >= 2) {
+			info->out[info->pos++] = ch;
+			info->out[info->pos] = '\0';
+			info->pc++;
+		}
 	}
-
-	if (out_len && *out_len > 0)
-		--(*out_len);
 }
 
-static int prints(char **out, u32 *out_len, const char *string, int width,
-		  int flags)
+static void prints(struct print_info *info, const char *string)
 {
-	int pc = 0;
-	width -= sbi_strlen(string);
-	if (!(flags & PAD_RIGHT)) {
-		for (; width > 0; --width) {
-			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
-			++pc;
-		}
-	}
-	for (; *string; ++string) {
-		printc(out, out_len, *string);
-		++pc;
-	}
-	for (; width > 0; --width) {
-		printc(out, out_len, ' ');
-		++pc;
+	info->wcnt += sbi_strlen(string);
+	if (!(info->flags & PAD_RIGHT)) {
+		for (; info->wcnt < info->width; info->wcnt++)
+			printc(info, info->flags & PAD_ZERO ? '0' : ' ');
 	}
-
-	return pc;
+	for (; *string; ++string)
+		printc(info, *string);
+	for (; info->wcnt < info->width; info->wcnt++)
+		printc(info, ' ');
 }
 
-static int printi(char **out, u32 *out_len, long long i,
-		  int width, int flags, int type)
+static void printi(struct print_info *info, long long i)
 {
-	int pc = 0;
 	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
 	unsigned long long u, b, t;
 
 	b = 10;
 	letbase = 'a';
-	if (type == 'o')
+	if (info->type == 'o')
 		b = 8;
-	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+	else if (info->type == 'x' || info->type == 'X'
+			 || info->type == 'p' || info->type == 'P') {
 		b = 16;
 		letbase &= ~0x20;
-		letbase |= type & 0x20;
+		letbase |= info->type & 0x20;
 	}
 
 	u = i;
 	sign = 0;
-	if (type == 'i' || type == 'd') {
-		if ((flags & PAD_SIGN) && i > 0)
+	if (info->type == 'i' || info->type == 'd') {
+		if ((info->flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
 			sign = '-';
@@ -214,26 +212,23 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ZERO) {
+	if (info->flags & PAD_ZERO) {
 		if (sign) {
-			printc(out, out_len, sign);
-			++pc;
-			--width;
+			printc(info, sign);
+			++info->wcnt;
 		}
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16 || b == 8) {
-				printc(out, out_len, '0');
-				++pc;
-				--width;
+				printc(info, '0');
+				++info->wcnt;
 			}
 			if (b == 16) {
-				printc(out, out_len, 'x' - 'a' + letbase);
-				++pc;
-				--width;
+				printc(info, 'x' - 'a' + letbase);
+				++info->wcnt;
 			}
 		}
 	} else {
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16)
 				*--s = 'x' - 'a' + letbase;
 			if (b == 16 || b == 8)
@@ -243,15 +238,16 @@ static int printi(char **out, u32 *out_len, long long i,
 			*--s = sign;
 	}
 
-	return pc + prints(out, out_len, s, width, flags);
+	prints(info, s);
 }
 
-static int print(char **out, u32 *out_len, const char *format, va_list args)
+static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
-	int width, flags, pc = 0;
-	char type, scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	char scr[2];
+	bool use_tbuf = (!info->out) ? true : false;
+	info->pos = 0;
+	info->pc = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -259,17 +255,14 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
-		console_tbuf_len = CONSOLE_TBUF_MAX;
-		tout = console_tbuf;
-		out = &tout;
-		out_len = &console_tbuf_len;
+		info->out = console_tbuf;
+		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	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 (use_tbuf && info->len - info->pos < 2) {
+			nputs_all(info->out, info->pos);
+			info->pos = 0;
 		}
 
 		if (*format == '%') {
@@ -279,21 +272,21 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			flags = 0;
+			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
 				case '-':
-					flags |= PAD_RIGHT;
+					info->flags |= PAD_RIGHT;
 					break;
 				case '+':
-					flags |= PAD_SIGN;
+					info->flags |= PAD_SIGN;
 					break;
 				case '#':
-					flags |= PAD_ALTERNATE;
+					info->flags |= PAD_ALTERNATE;
 					break;
 				case '0':
-					flags |= PAD_ZERO;
+					info->flags |= PAD_ZERO;
 					break;
 				case ' ':
 				case '\'':
@@ -306,153 +299,160 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
-			if (flags & PAD_RIGHT)
-				flags &= ~PAD_ZERO;
+			if (info->flags & PAD_RIGHT)
+				info->flags &= ~PAD_ZERO;
 			/* Get width */
-			width = 0;
+			info->wcnt = 0;
+			info->width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-				width *= 10;
-				width += *format - '0';
+				info->width *= 10;
+				info->width += *format - '0';
 			}
+			info->type = *format;
 			if (*format == 's') {
 				char *s = va_arg(args, char *);
-				pc += prints(out, out_len, s ? s : "(null)",
-					     width, flags);
+				prints(info, s ? s : "(null)");
 				continue;
 			}
 			if ((*format == 'd') || (*format == 'i')) {
-				pc += printi(out, out_len, va_arg(args, int),
-					     width, flags, *format);
+				printi(info, va_arg(args, int));
 				continue;
 			}
 			if ((*format == 'u') || (*format == 'o')
 					 || (*format == 'x') || (*format == 'X')) {
-				pc += printi(out, out_len, va_arg(args, unsigned int),
-					     width, flags, *format);
+				printi(info, va_arg(args, unsigned int));
 				continue;
 			}
 			if ((*format == 'p') || (*format == 'P')) {
-				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
-					     width, flags, *format);
+				printi(info, (uintptr_t)va_arg(args, void*));
 				continue;
 			}
 			if (*format == 'l') {
-				type = 'i';
+				info->type = 'i';
 				if (format[1] == 'l') {
 					++format;
 					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
-						type = *format;
+						info->type = *format;
 					}
-					pc += printi(out, out_len, va_arg(args, long long),
-						width, flags, type);
+					printi(info, va_arg(args, long long));
 					continue;
 				}
 				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-					type = *format;
+					info->type = *format;
 				}
-				if ((type == 'd') || (type == 'i'))
-					pc += printi(out, out_len, va_arg(args, long),
-					     width, flags, type);
+				if ((info->type == 'd') || (info->type == 'i'))
+					printi(info, va_arg(args, long));
 				else
-					pc += printi(out, out_len, va_arg(args, unsigned long),
-					     width, flags, type);
+					printi(info, va_arg(args, unsigned long));
 				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
 				scr[0] = va_arg(args, int);
 				scr[1] = '\0';
-				pc += prints(out, out_len, scr, width, flags);
+				prints(info, scr);
 				continue;
 			}
 		} else {
 literal:
-			printc(out, out_len, *format);
-			++pc;
+			printc(info, *format);
 		}
 	}
 
-	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
-		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
-
-	return pc;
+	if (use_tbuf && info->pos > 0)
+		nputs_all(info->out, info->pos);
 }
 
 int sbi_sprintf(char *out, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = 0;
+
 
 	if (unlikely(!out))
 		sbi_panic("sbi_sprintf called with NULL output string\n");
 
 	va_start(args, format);
-	retval = print(&out, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = out_sz;
+
 
 	if (unlikely(!out && out_sz != 0))
 		sbi_panic("sbi_snprintf called with NULL output string and "
 			  "output size is not zero\n");
 
 	va_start(args, format);
-	retval = print(&out, &out_sz, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_printf(const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	retval = print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_dprintf(const char *format, ...)
 {
 	va_list args;
-	int retval = 0;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	va_start(args, format);
 	if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) {
 		spin_lock(&console_out_lock);
-		retval = print(NULL, NULL, format, args);
+		print(&info, format, args);
 		spin_unlock(&console_out_lock);
 	}
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 void sbi_panic(const char *format, ...)
 {
 	va_list args;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-- 
2.39.2



From wxjstz at 126.com  Tue Jun  6 06:29:44 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue,  6 Jun 2023 21:29:44 +0800
Subject: [PATCH v3 12/12] lib: sbi: Fix timing of clearing tbuf
Message-ID: <20230606132944.1240924-1-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7608bbd..dfc24af 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -18,6 +18,8 @@
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
 #define PAD_SIGN 8
+#define USED_TBUF (1 << (8 * sizeof(int) - 1))
+
 #define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
@@ -155,6 +157,11 @@ static void printc(struct print_info *info, char ch)
 			info->pc++;
 		}
 	}
+
+	if ((info->flags & USED_TBUF) && info->len - info->pos < 2) {
+		nputs_all(info->out, info->pos);
+		info->pos = 0;
+	}
 }
 
 static void prints(struct print_info *info, const char *string)
@@ -260,11 +267,6 @@ static void print(struct print_info *info, const char *format, va_list args)
 	}
 
 	for (; *format != 0; ++format) {
-		if (use_tbuf && info->len - info->pos < 2) {
-			nputs_all(info->out, info->pos);
-			info->pos = 0;
-		}
-
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -299,6 +301,8 @@ static void print(struct print_info *info, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (use_tbuf)
+				info->flags |= USED_TBUF;
 			if (info->flags & PAD_RIGHT)
 				info->flags &= ~PAD_ZERO;
 			/* Get width */
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:50 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:50 +0800
Subject: [PATCH v4 00/13] Improve sbi_console
Message-ID: <20230608073003.1565710-1-wxjstz@126.com>

v4 changes:
- PATCH10: Simplify printc
- add PATCH11, handle special case

v3 changes:
- PATCH11: Simplify get info->type
- PATCH12: Change the way to keep USED_TBUF by and to reset it by use_tbuf

v2 changes:
- add patch 10-12

Xiang W (13):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf
  lib: sbi: Fix missing '\0' when buffer szie equal 1

 lib/sbi/sbi_console.c | 413 ++++++++++++++++++++++--------------------
 1 file changed, 212 insertions(+), 201 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:52 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:52 +0800
Subject: [PATCH v4 02/13] lib: sbi: Fix how print gets flags
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:55 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:55 +0800
Subject: [PATCH v4 05/13] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:57 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:57 +0800
Subject: [PATCH v4 07/13] lib: sbi: print add 'o' type
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:53 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:53 +0800
Subject: [PATCH v4 03/13] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:59 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:59 +0800
Subject: [PATCH v4 09/13] lib: sbi: Simplify prints
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-10-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:54 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:54 +0800
Subject: [PATCH v4 04/13] lib: sbi: Add '+' flags for print
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:58 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:58 +0800
Subject: [PATCH v4 08/13] lib: sbi: Fix printi
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:29:51 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:51 +0800
Subject: [PATCH v4 01/13] lib: sbi: Fix missing contine in print
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-2-wxjstz@126.com>

Missing continue after print %lu %ld %lx ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:30:00 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:30:00 +0800
Subject: [PATCH v4 10/13] lib: sbi: sbi_console.c code re-layout
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-11-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:32:14 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:32:14 +0800
Subject: [PATCH v4 13/13] lib: sbi: Fix missing '\0' when buffer szie equal 1
In-Reply-To: <20230608073214.1566095-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
 <20230608073214.1566095-1-wxjstz@126.com>
Message-ID: <20230608073214.1566095-3-wxjstz@126.com>

Fix special case: sbi_snprintf(out, 1, ...), The previous code will
not fill the buffer with any char.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7d811e7..81555f3 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -157,6 +157,14 @@ static void printc(struct print_info *info, char ch)
 	/* The buffer is long enough to add new characters */
 	if (info->len - info->pos > 1)
 		goto append;
+
+	/*
+	 * special case: sbi_snprintf(out, 1, ...);
+	 * This case never jumps to append, so add '\0' here
+	 */
+	if (info->pos == 0)
+		info->out[0] = '\0';
+
 	return;
 
 append:
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:32:13 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:32:13 +0800
Subject: [PATCH v4 12/13] lib: sbi: Fix timing of clearing tbuf
In-Reply-To: <20230608073214.1566095-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
 <20230608073214.1566095-1-wxjstz@126.com>
Message-ID: <20230608073214.1566095-2-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f6ab14..7d811e7 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -18,6 +18,8 @@
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
 #define PAD_SIGN 8
+#define USED_TBUF (1 << (8 * sizeof(int) - 1))
+
 #define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
@@ -161,6 +163,11 @@ append:
 	info->out[info->pos++] = ch;
 	info->out[info->pos] = '\0';
 	info->pc++;
+
+	if ((info->flags & USED_TBUF) && (info->len - info->pos <= 1)) {
+		nputs_all(info->out, info->pos);
+		info->pos = 0;
+	}
 }
 
 static void prints(struct print_info *info, const char *string)
@@ -266,11 +273,6 @@ static void print(struct print_info *info, const char *format, va_list args)
 	}
 
 	for (; *format != 0; ++format) {
-		if (use_tbuf && (info->len - info->pos <= 1)) {
-			nputs_all(info->out, info->pos);
-			info->pos = 0;
-		}
-
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -305,6 +307,8 @@ static void print(struct print_info *info, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (use_tbuf)
+				info->flags |= USED_TBUF;
 			if (info->flags & PAD_RIGHT)
 				info->flags &= ~PAD_ZERO;
 			/* Get width */
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:32:12 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:32:12 +0800
Subject: [PATCH v4 11/13] lib: sbi: Add print_info for sbi_console.c
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073214.1566095-1-wxjstz@126.com>

Create a structure print_info for print, this structure simplifies
parameter passing.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 232 ++++++++++++++++++++++--------------------
 1 file changed, 119 insertions(+), 113 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index af93f51..7f6ab14 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -27,11 +27,22 @@
 
 typedef __builtin_va_list va_list;
 
+struct print_info {
+	char *out;
+	int len;
+	int pos;
+	int pc;
+	int flags;
+	int width;
+	int wcnt;
+	char type;
+};
+
 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)
 {
 	if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
@@ -128,70 +139,63 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-static void printc(char **out, u32 *out_len, char ch)
+static void printc(struct print_info *info, char ch)
 {
-	if (!out) {
+	/* output to the console */
+	if (info->out == NULL) {
 		sbi_putc(ch);
+		info->pc++;
 		return;
 	}
 
-	/*
-	 * The *printf entry point functions have enforced that (*out) can
-	 * only be null when out_len is non-null and its value is zero.
-	 */
-	if (!out_len || *out_len > 1) {
-		*(*out)++ = ch;
-		**out = '\0';
-	}
+	/* unknown buffer length */
+	if (info->len == 0)
+		goto append;
+
+	/* The buffer is long enough to add new characters */
+	if (info->len - info->pos > 1)
+		goto append;
+	return;
 
-	if (out_len && *out_len > 0)
-		--(*out_len);
+append:
+	info->out[info->pos++] = ch;
+	info->out[info->pos] = '\0';
+	info->pc++;
 }
 
-static int prints(char **out, u32 *out_len, const char *string, int width,
-		  int flags)
+static void prints(struct print_info *info, const char *string)
 {
-	int pc = 0;
-	width -= sbi_strlen(string);
-	if (!(flags & PAD_RIGHT)) {
-		for (; width > 0; --width) {
-			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
-			++pc;
-		}
-	}
-	for (; *string; ++string) {
-		printc(out, out_len, *string);
-		++pc;
+	info->wcnt += sbi_strlen(string);
+	if (!(info->flags & PAD_RIGHT)) {
+		for (; info->wcnt < info->width; info->wcnt++)
+			printc(info, info->flags & PAD_ZERO ? '0' : ' ');
 	}
-	for (; width > 0; --width) {
-		printc(out, out_len, ' ');
-		++pc;
-	}
-
-	return pc;
+	for (; *string; ++string)
+		printc(info, *string);
+	for (; info->wcnt < info->width; info->wcnt++)
+		printc(info, ' ');
 }
 
-static int printi(char **out, u32 *out_len, long long i,
-		  int width, int flags, int type)
+static void printi(struct print_info *info, long long i)
 {
-	int pc = 0;
 	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
 	unsigned long long u, b, t;
 
 	b = 10;
 	letbase = 'a';
-	if (type == 'o')
+	if (info->type == 'o')
 		b = 8;
-	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+	else if (info->type == 'x' || info->type == 'X'
+			 || info->type == 'p' || info->type == 'P') {
 		b = 16;
 		letbase &= ~0x20;
-		letbase |= type & 0x20;
+		letbase |= info->type & 0x20;
 	}
 
 	u = i;
 	sign = 0;
-	if (type == 'i' || type == 'd') {
-		if ((flags & PAD_SIGN) && i > 0)
+	if (info->type == 'i' || info->type == 'd') {
+		if ((info->flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
 			sign = '-';
@@ -214,26 +218,23 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ZERO) {
+	if (info->flags & PAD_ZERO) {
 		if (sign) {
-			printc(out, out_len, sign);
-			++pc;
-			--width;
+			printc(info, sign);
+			++info->wcnt;
 		}
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16 || b == 8) {
-				printc(out, out_len, '0');
-				++pc;
-				--width;
+				printc(info, '0');
+				++info->wcnt;
 			}
 			if (b == 16) {
-				printc(out, out_len, 'x' - 'a' + letbase);
-				++pc;
-				--width;
+				printc(info, 'x' - 'a' + letbase);
+				++info->wcnt;
 			}
 		}
 	} else {
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16)
 				*--s = 'x' - 'a' + letbase;
 			if (b == 16 || b == 8)
@@ -243,15 +244,16 @@ static int printi(char **out, u32 *out_len, long long i,
 			*--s = sign;
 	}
 
-	return pc + prints(out, out_len, s, width, flags);
+	prints(info, s);
 }
 
-static int print(char **out, u32 *out_len, const char *format, va_list args)
+static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
-	int width, flags, pc = 0;
-	char type, scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	char scr[2];
+	bool use_tbuf = (!info->out) ? true : false;
+	info->pos = 0;
+	info->pc = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -259,17 +261,14 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
-		console_tbuf_len = CONSOLE_TBUF_MAX;
-		tout = console_tbuf;
-		out = &tout;
-		out_len = &console_tbuf_len;
+		info->out = console_tbuf;
+		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	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 (use_tbuf && (info->len - info->pos <= 1)) {
+			nputs_all(info->out, info->pos);
+			info->pos = 0;
 		}
 
 		if (*format == '%') {
@@ -279,21 +278,21 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			flags = 0;
+			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
 				case '-':
-					flags |= PAD_RIGHT;
+					info->flags |= PAD_RIGHT;
 					break;
 				case '+':
-					flags |= PAD_SIGN;
+					info->flags |= PAD_SIGN;
 					break;
 				case '#':
-					flags |= PAD_ALTERNATE;
+					info->flags |= PAD_ALTERNATE;
 					break;
 				case '0':
-					flags |= PAD_ZERO;
+					info->flags |= PAD_ZERO;
 					break;
 				case ' ':
 				case '\'':
@@ -306,153 +305,160 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
-			if (flags & PAD_RIGHT)
-				flags &= ~PAD_ZERO;
+			if (info->flags & PAD_RIGHT)
+				info->flags &= ~PAD_ZERO;
 			/* Get width */
-			width = 0;
+			info->wcnt = 0;
+			info->width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-				width *= 10;
-				width += *format - '0';
+				info->width *= 10;
+				info->width += *format - '0';
 			}
+			info->type = *format;
 			if (*format == 's') {
 				char *s = va_arg(args, char *);
-				pc += prints(out, out_len, s ? s : "(null)",
-					     width, flags);
+				prints(info, s ? s : "(null)");
 				continue;
 			}
 			if ((*format == 'd') || (*format == 'i')) {
-				pc += printi(out, out_len, va_arg(args, int),
-					     width, flags, *format);
+				printi(info, va_arg(args, int));
 				continue;
 			}
 			if ((*format == 'u') || (*format == 'o')
 					 || (*format == 'x') || (*format == 'X')) {
-				pc += printi(out, out_len, va_arg(args, unsigned int),
-					     width, flags, *format);
+				printi(info, va_arg(args, unsigned int));
 				continue;
 			}
 			if ((*format == 'p') || (*format == 'P')) {
-				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
-					     width, flags, *format);
+				printi(info, (uintptr_t)va_arg(args, void*));
 				continue;
 			}
 			if (*format == 'l') {
-				type = 'i';
+				info->type = 'i';
 				if (format[1] == 'l') {
 					++format;
 					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
-						type = *format;
+						info->type = *format;
 					}
-					pc += printi(out, out_len, va_arg(args, long long),
-						width, flags, type);
+					printi(info, va_arg(args, long long));
 					continue;
 				}
 				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-					type = *format;
+					info->type = *format;
 				}
-				if ((type == 'd') || (type == 'i'))
-					pc += printi(out, out_len, va_arg(args, long),
-					     width, flags, type);
+				if ((info->type == 'd') || (info->type == 'i'))
+					printi(info, va_arg(args, long));
 				else
-					pc += printi(out, out_len, va_arg(args, unsigned long),
-					     width, flags, type);
+					printi(info, va_arg(args, unsigned long));
 				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
 				scr[0] = va_arg(args, int);
 				scr[1] = '\0';
-				pc += prints(out, out_len, scr, width, flags);
+				prints(info, scr);
 				continue;
 			}
 		} else {
 literal:
-			printc(out, out_len, *format);
-			++pc;
+			printc(info, *format);
 		}
 	}
 
-	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
-		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
-
-	return pc;
+	if (use_tbuf && info->pos > 0)
+		nputs_all(info->out, info->pos);
 }
 
 int sbi_sprintf(char *out, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = 0;
+
 
 	if (unlikely(!out))
 		sbi_panic("sbi_sprintf called with NULL output string\n");
 
 	va_start(args, format);
-	retval = print(&out, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = out_sz;
+
 
 	if (unlikely(!out && out_sz != 0))
 		sbi_panic("sbi_snprintf called with NULL output string and "
 			  "output size is not zero\n");
 
 	va_start(args, format);
-	retval = print(&out, &out_sz, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_printf(const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	retval = print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_dprintf(const char *format, ...)
 {
 	va_list args;
-	int retval = 0;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	va_start(args, format);
 	if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) {
 		spin_lock(&console_out_lock);
-		retval = print(NULL, NULL, format, args);
+		print(&info, format, args);
 		spin_unlock(&console_out_lock);
 	}
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 void sbi_panic(const char *format, ...)
 {
 	va_list args;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 00:36:30 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu, 08 Jun 2023 15:36:30 +0800
Subject: [PATCH v4 00/13] Improve sbi_console
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <c9b1ab7f2345151b8bf00388efca54fe32ae37d7.camel@126.com>

? 2023-06-08???? 15:29 +0800?Xiang W???
> v4 changes:
> - PATCH10: Simplify printc
> - add PATCH11, handle special case

v4 changes:
- PATCH11: Simplify printc
- add PATCH13, handle special case

> 
> v3 changes:
> - PATCH11: Simplify get info->type
> - PATCH12: Change the way to keep USED_TBUF by and to reset it by use_tbuf
> 
> v2 changes:
> - add patch 10-12
> 
> Xiang W (13):
> ? lib: sbi: Fix missing contine in print
> ? lib: sbi: Fix how print gets flags
> ? lib: sbi: print not fill '0' when left-aligned
> ? lib: sbi: Add '+' flags for print
> ? lib: sbi: Add ' ' '\'' flags for print
> ? lib: sbi: implifying the parameters of printi
> ? lib: sbi: print add 'o' type
> ? lib: sbi: Fix printi
> ? lib: sbi: Simplify prints
> ? lib: sbi: sbi_console.c code re-layout
> ? lib: sbi: Add print_info for sbi_console.c
> ? lib: sbi: Fix timing of clearing tbuf
> ? lib: sbi: Fix missing '\0' when buffer szie equal 1
> 
> ?lib/sbi/sbi_console.c | 413 ++++++++++++++++++++++--------------------
> ?1 file changed, 212 insertions(+), 201 deletions(-)
> 



From wxjstz at 126.com  Thu Jun  8 00:29:56 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu,  8 Jun 2023 15:29:56 +0800
Subject: [PATCH v4 06/13] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230608073003.1565710-1-wxjstz@126.com>
References: <20230608073003.1565710-1-wxjstz@126.com>
Message-ID: <20230608073003.1565710-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:24 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:24 +0800
Subject: [PATCH v5 08/14] lib: sbi: Fix printi
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-9-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:19 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:19 +0800
Subject: [PATCH v5 03/14] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-4-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 97ee328..b18f9c5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:17 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:17 +0800
Subject: [PATCH v5 01/14] lib: sbi: Fix missing contine in print
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-2-wxjstz@126.com>

Missing continue after print %lu %ld %lx ...

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..1f0727c 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						     va_arg(args, long), 10, 1,
 						     width, flags, '0');
 				}
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:20 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:20 +0800
Subject: [PATCH v5 04/14] lib: sbi: Add '+' flags for print
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b18f9c5..a616316 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:21 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:21 +0800
Subject: [PATCH v5 05/14] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-6-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a616316..7f32f81 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:26 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:26 +0800
Subject: [PATCH v5 10/14] lib: sbi: sbi_console.c code re-layout
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-11-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:25 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:25 +0800
Subject: [PATCH v5 09/14] lib: sbi: Simplify prints
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-10-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:23 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:23 +0800
Subject: [PATCH v5 07/14] lib: sbi: print add 'o' type
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-8-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:22 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:22 +0800
Subject: [PATCH v5 06/14] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-7-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 126 ++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 7f32f81..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,45 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
 				continue;
 			}
 			if (*format == 'c') {
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:16 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:16 +0800
Subject: [PATCH v5 00/14] Improve sbi_console
Message-ID: <20230609033430.84471-1-wxjstz@126.com>

v5 changes:
- PATCH12: fix printf("%%") missing USED_TBUF;  
- add PATCH14, Fix invalid directive print

v4 changes:
- PATCH11: Simplify printc
- add PATCH13, handle special case

v3 changes:
- PATCH11: Simplify get info->type
- PATCH12: Change the way to keep USED_TBUF by and to reset it by use_tbuf

v2 changes:
- add patch 10-12

Xiang W (14):
  lib: sbi: Fix missing contine in print
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf
  lib: sbi: Fix missing '\0' when buffer szie equal 1
  lib: sbi: Fix invalid directive print

 lib/sbi/sbi_console.c | 421 ++++++++++++++++++++++--------------------
 1 file changed, 218 insertions(+), 203 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:34:18 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:34:18 +0800
Subject: [PATCH v5 02/14] lib: sbi: Fix how print gets flags
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033430.84471-3-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 1f0727c..97ee328 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:35:38 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:35:38 +0800
Subject: [PATCH v5 11/14] lib: sbi: Add print_info for sbi_console.c
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033538.84664-1-wxjstz@126.com>

Create a structure print_info for print, this structure simplifies
parameter passing.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 235 +++++++++++++++++++++---------------------
 1 file changed, 120 insertions(+), 115 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index af93f51..c227b0f 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -27,11 +27,22 @@
 
 typedef __builtin_va_list va_list;
 
+struct print_info {
+	char *out;
+	int len;
+	int pos;
+	int pc;
+	int flags;
+	int width;
+	int wcnt;
+	char type;
+};
+
 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)
 {
 	if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
@@ -128,70 +139,63 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-static void printc(char **out, u32 *out_len, char ch)
+static void printc(struct print_info *info, char ch)
 {
-	if (!out) {
+	/* output to the console */
+	if (info->out == NULL) {
 		sbi_putc(ch);
+		info->pc++;
 		return;
 	}
 
-	/*
-	 * The *printf entry point functions have enforced that (*out) can
-	 * only be null when out_len is non-null and its value is zero.
-	 */
-	if (!out_len || *out_len > 1) {
-		*(*out)++ = ch;
-		**out = '\0';
-	}
+	/* unknown buffer length */
+	if (info->len == 0)
+		goto append;
 
-	if (out_len && *out_len > 0)
-		--(*out_len);
+	/* The buffer is long enough to add new characters */
+	if (info->len - info->pos > 1)
+		goto append;
+	return;
+
+append:
+	info->out[info->pos++] = ch;
+	info->out[info->pos] = '\0';
+	info->pc++;
 }
 
-static int prints(char **out, u32 *out_len, const char *string, int width,
-		  int flags)
+static void prints(struct print_info *info, const char *string)
 {
-	int pc = 0;
-	width -= sbi_strlen(string);
-	if (!(flags & PAD_RIGHT)) {
-		for (; width > 0; --width) {
-			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
-			++pc;
-		}
-	}
-	for (; *string; ++string) {
-		printc(out, out_len, *string);
-		++pc;
-	}
-	for (; width > 0; --width) {
-		printc(out, out_len, ' ');
-		++pc;
+	info->wcnt += sbi_strlen(string);
+	if (!(info->flags & PAD_RIGHT)) {
+		for (; info->wcnt < info->width; info->wcnt++)
+			printc(info, info->flags & PAD_ZERO ? '0' : ' ');
 	}
-
-	return pc;
+	for (; *string; ++string)
+		printc(info, *string);
+	for (; info->wcnt < info->width; info->wcnt++)
+		printc(info, ' ');
 }
 
-static int printi(char **out, u32 *out_len, long long i,
-		  int width, int flags, int type)
+static void printi(struct print_info *info, long long i)
 {
-	int pc = 0;
 	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
 	unsigned long long u, b, t;
 
 	b = 10;
 	letbase = 'a';
-	if (type == 'o')
+	if (info->type == 'o')
 		b = 8;
-	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+	else if (info->type == 'x' || info->type == 'X'
+			 || info->type == 'p' || info->type == 'P') {
 		b = 16;
 		letbase &= ~0x20;
-		letbase |= type & 0x20;
+		letbase |= info->type & 0x20;
 	}
 
 	u = i;
 	sign = 0;
-	if (type == 'i' || type == 'd') {
-		if ((flags & PAD_SIGN) && i > 0)
+	if (info->type == 'i' || info->type == 'd') {
+		if ((info->flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
 			sign = '-';
@@ -214,26 +218,23 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ZERO) {
+	if (info->flags & PAD_ZERO) {
 		if (sign) {
-			printc(out, out_len, sign);
-			++pc;
-			--width;
+			printc(info, sign);
+			++info->wcnt;
 		}
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16 || b == 8) {
-				printc(out, out_len, '0');
-				++pc;
-				--width;
+				printc(info, '0');
+				++info->wcnt;
 			}
 			if (b == 16) {
-				printc(out, out_len, 'x' - 'a' + letbase);
-				++pc;
-				--width;
+				printc(info, 'x' - 'a' + letbase);
+				++info->wcnt;
 			}
 		}
 	} else {
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16)
 				*--s = 'x' - 'a' + letbase;
 			if (b == 16 || b == 8)
@@ -243,15 +244,16 @@ static int printi(char **out, u32 *out_len, long long i,
 			*--s = sign;
 	}
 
-	return pc + prints(out, out_len, s, width, flags);
+	prints(info, s);
 }
 
-static int print(char **out, u32 *out_len, const char *format, va_list args)
+static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
-	int width, flags, pc = 0;
-	char type, scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	char scr[2];
+	bool use_tbuf = (!info->out) ? true : false;
+	info->pos = 0;
+	info->pc = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -259,19 +261,15 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
-		console_tbuf_len = CONSOLE_TBUF_MAX;
-		tout = console_tbuf;
-		out = &tout;
-		out_len = &console_tbuf_len;
+		info->out = console_tbuf;
+		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	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 (use_tbuf && (info->len - info->pos <= 1)) {
+			nputs_all(info->out, info->pos);
+			info->pos = 0;
+		}		
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -279,21 +277,21 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			flags = 0;
+			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
 				case '-':
-					flags |= PAD_RIGHT;
+					info->flags |= PAD_RIGHT;
 					break;
 				case '+':
-					flags |= PAD_SIGN;
+					info->flags |= PAD_SIGN;
 					break;
 				case '#':
-					flags |= PAD_ALTERNATE;
+					info->flags |= PAD_ALTERNATE;
 					break;
 				case '0':
-					flags |= PAD_ZERO;
+					info->flags |= PAD_ZERO;
 					break;
 				case ' ':
 				case '\'':
@@ -306,153 +304,160 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
-			if (flags & PAD_RIGHT)
-				flags &= ~PAD_ZERO;
+			if (info->flags & PAD_RIGHT)
+				info->flags &= ~PAD_ZERO;
 			/* Get width */
-			width = 0;
+			info->width = 0;
+			info->wcnt = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-				width *= 10;
-				width += *format - '0';
+				info->width *= 10;
+				info->width += *format - '0';
 			}
+			info->type = *format;
 			if (*format == 's') {
 				char *s = va_arg(args, char *);
-				pc += prints(out, out_len, s ? s : "(null)",
-					     width, flags);
+				prints(info, s ? s : "(null)");
 				continue;
 			}
 			if ((*format == 'd') || (*format == 'i')) {
-				pc += printi(out, out_len, va_arg(args, int),
-					     width, flags, *format);
+				printi(info, va_arg(args, int));
 				continue;
 			}
 			if ((*format == 'u') || (*format == 'o')
 					 || (*format == 'x') || (*format == 'X')) {
-				pc += printi(out, out_len, va_arg(args, unsigned int),
-					     width, flags, *format);
+				printi(info, va_arg(args, unsigned int));
 				continue;
 			}
 			if ((*format == 'p') || (*format == 'P')) {
-				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
-					     width, flags, *format);
+				printi(info, (uintptr_t)va_arg(args, void*));
 				continue;
 			}
 			if (*format == 'l') {
-				type = 'i';
+				info->type = 'i';
 				if (format[1] == 'l') {
 					++format;
 					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
-						type = *format;
+						info->type = *format;
 					}
-					pc += printi(out, out_len, va_arg(args, long long),
-						width, flags, type);
+					printi(info, va_arg(args, long long));
 					continue;
 				}
 				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-					type = *format;
+					info->type = *format;
 				}
-				if ((type == 'd') || (type == 'i'))
-					pc += printi(out, out_len, va_arg(args, long),
-					     width, flags, type);
+				if ((info->type == 'd') || (info->type == 'i'))
+					printi(info, va_arg(args, long));
 				else
-					pc += printi(out, out_len, va_arg(args, unsigned long),
-					     width, flags, type);
+					printi(info, va_arg(args, unsigned long));
 				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
 				scr[0] = va_arg(args, int);
 				scr[1] = '\0';
-				pc += prints(out, out_len, scr, width, flags);
+				prints(info, scr);
 				continue;
 			}
 		} else {
 literal:
-			printc(out, out_len, *format);
-			++pc;
+			printc(info, *format);
 		}
 	}
 
-	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
-		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
-
-	return pc;
+	if (use_tbuf && info->pos > 0)
+		nputs_all(info->out, info->pos);
 }
 
 int sbi_sprintf(char *out, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = 0;
+
 
 	if (unlikely(!out))
 		sbi_panic("sbi_sprintf called with NULL output string\n");
 
 	va_start(args, format);
-	retval = print(&out, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = out_sz;
+
 
 	if (unlikely(!out && out_sz != 0))
 		sbi_panic("sbi_snprintf called with NULL output string and "
 			  "output size is not zero\n");
 
 	va_start(args, format);
-	retval = print(&out, &out_sz, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_printf(const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	retval = print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_dprintf(const char *format, ...)
 {
 	va_list args;
-	int retval = 0;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	va_start(args, format);
 	if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) {
 		spin_lock(&console_out_lock);
-		retval = print(NULL, NULL, format, args);
+		print(&info, format, args);
 		spin_unlock(&console_out_lock);
 	}
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 void sbi_panic(const char *format, ...)
 {
 	va_list args;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:36:24 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:36:24 +0800
Subject: [PATCH v5 13/14] lib: sbi: Fix missing '\0' when buffer szie equal 1
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033624.84865-1-wxjstz@126.com>

Fix special case: sbi_snprintf(out, 1, ...), The previous code will
not fill the buffer with any char.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 2eefee1..f7fd761 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -157,6 +157,14 @@ static void printc(struct print_info *info, char ch)
 	/* The buffer is long enough to add new characters */
 	if (info->len - info->pos > 1)
 		goto append;
+
+	/*
+	 * special case: sbi_snprintf(out, 1, ...);
+	 * This case never jumps to append, so add '\0' here
+	 */
+	if (info->pos == 0)
+		info->out[0] = '\0';
+
 	return;
 
 append:
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:36:43 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:36:43 +0800
Subject: [PATCH v5 14/14] lib: sbi: Fix invalid directive print
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033643.85014-1-wxjstz@126.com>

before fix:
> printf("%1234"); /* print noting */
after fix:
> printf("%1234"); /* print %1234 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index f7fd761..a4ee1e5 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -266,6 +266,7 @@ static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
 	char scr[2];
+	const char *format_bak;
 	bool use_tbuf = (!info->out) ? true : false;
 	info->pos = 0;
 	info->pc = 0;
@@ -285,6 +286,8 @@ static void print(struct print_info *info, const char *format, va_list args)
 		if (use_tbuf)
 			info->flags |= USED_TBUF;
 		if (*format == '%') {
+			/* need restore when the directive is invalid */
+			format_bak = format;
 			++format;
 			if (*format == '\0')
 				break;
@@ -377,10 +380,11 @@ static void print(struct print_info *info, const char *format, va_list args)
 				prints(info, scr);
 				continue;
 			}
-		} else {
-literal:
-			printc(info, *format);
+			/* invalid directive */
+			format = format_bak;
 		}
+literal:
+		printc(info, *format);
 	}
 
 	if (use_tbuf && info->pos > 0)
-- 
2.39.2



From wxjstz at 126.com  Thu Jun  8 20:36:06 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri,  9 Jun 2023 11:36:06 +0800
Subject: [PATCH v5 12/14] lib: sbi: Fix timing of clearing tbuf
In-Reply-To: <20230609033430.84471-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
Message-ID: <20230609033606.84769-1-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index c227b0f..2eefee1 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -18,6 +18,8 @@
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
 #define PAD_SIGN 8
+#define USED_TBUF (1 << (8 * sizeof(int) - 1))
+
 #define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
@@ -161,6 +163,11 @@ append:
 	info->out[info->pos++] = ch;
 	info->out[info->pos] = '\0';
 	info->pc++;
+
+	if ((info->flags & USED_TBUF) && (info->len - info->pos <= 1)) {
+		nputs_all(info->out, info->pos);
+		info->pos = 0;
+	}
 }
 
 static void prints(struct print_info *info, const char *string)
@@ -266,10 +273,9 @@ static void print(struct print_info *info, const char *format, va_list args)
 	}
 
 	for (; *format != 0; ++format) {
-		if (use_tbuf && (info->len - info->pos <= 1)) {
-			nputs_all(info->out, info->pos);
-			info->pos = 0;
-		}		
+		info->flags = 0;
+		if (use_tbuf)
+			info->flags |= USED_TBUF;
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -277,7 +283,6 @@ static void print(struct print_info *info, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
-- 
2.39.2



From jrtc27 at jrtc27.com  Thu Jun  8 21:15:38 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Fri, 9 Jun 2023 05:15:38 +0100
Subject: [PATCH v5 14/14] lib: sbi: Fix invalid directive print
In-Reply-To: <20230609033643.85014-1-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
 <20230609033643.85014-1-wxjstz@126.com>
Message-ID: <3E9E84E3-2ED5-4AAC-8560-3D1F37EB9D63@jrtc27.com>

On 9 Jun 2023, at 04:36, Xiang W <wxjstz at 126.com> wrote:
> 
> before fix:
>> printf("%1234"); /* print noting */
> after fix:
>> printf("%1234"); /* print %1234 */
> 
> Signed-off-by: Xiang W <wxjstz at 126.com>

Who cares what it does? It?s UB. Going out of your way to make it do a
specific thing with extra code is a waste of time and obfuscation.

Turn on -Wformat -Werror=format and get rid of broken code.

Jess

> ---
> lib/sbi/sbi_console.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> index f7fd761..a4ee1e5 100644
> --- a/lib/sbi/sbi_console.c
> +++ b/lib/sbi/sbi_console.c
> @@ -266,6 +266,7 @@ static void print(struct print_info *info, const char *format, va_list args)
> {
> bool flags_done;
> char scr[2];
> + const char *format_bak;
> bool use_tbuf = (!info->out) ? true : false;
> info->pos = 0;
> info->pc = 0;
> @@ -285,6 +286,8 @@ static void print(struct print_info *info, const char *format, va_list args)
> if (use_tbuf)
> info->flags |= USED_TBUF;
> if (*format == '%') {
> + /* need restore when the directive is invalid */
> + format_bak = format;
> ++format;
> if (*format == '\0')
> break;
> @@ -377,10 +380,11 @@ static void print(struct print_info *info, const char *format, va_list args)
> prints(info, scr);
> continue;
> }
> - } else {
> -literal:
> - printc(info, *format);
> + /* invalid directive */
> + format = format_bak;
> }
> +literal:
> + printc(info, *format);
> }
> 
> if (use_tbuf && info->pos > 0)
> -- 
> 2.39.2
> 



From jrtc27 at jrtc27.com  Thu Jun  8 21:16:49 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Fri, 9 Jun 2023 05:16:49 +0100
Subject: [PATCH v5 01/14] lib: sbi: Fix missing contine in print
In-Reply-To: <20230609033430.84471-2-wxjstz@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
 <20230609033430.84471-2-wxjstz@126.com>
Message-ID: <1794DCF8-26E3-44EB-8598-C6581AF29C85@jrtc27.com>

On 9 Jun 2023, at 04:34, Xiang W <wxjstz at 126.com> wrote:
> 
> Missing continue after print %lu %ld %lx ...

What kind of commit message is this? What?s the exact bug?

Jess

> Signed-off-by: Xiang W <wxjstz at 126.com>
> ---
> lib/sbi/sbi_console.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> index 168dffd..1f0727c 100644
> --- a/lib/sbi/sbi_console.c
> +++ b/lib/sbi/sbi_console.c
> @@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
>     va_arg(args, long), 10, 1,
>     width, flags, '0');
> }
> + continue;
> }
> if (*format == 'c') {
> /* char are converted to int then pushed on the stack */
> -- 
> 2.39.2
> 



From wxjstz at 126.com  Thu Jun  8 23:29:29 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 09 Jun 2023 14:29:29 +0800
Subject: [PATCH v5 01/14] lib: sbi: Fix missing contine in print
In-Reply-To: <1794DCF8-26E3-44EB-8598-C6581AF29C85@jrtc27.com>
References: <20230609033430.84471-1-wxjstz@126.com>
	 <20230609033430.84471-2-wxjstz@126.com>
	 <1794DCF8-26E3-44EB-8598-C6581AF29C85@jrtc27.com>
Message-ID: <6179f4a815fd4282b445bc8fc2520bb933de1def.camel@126.com>

? 2023-06-09???? 05:16 +0100?Jessica Clarke???
> On 9 Jun 2023, at 04:34, Xiang W <wxjstz at 126.com> wrote:
> > 
> > Missing continue after print %lu %ld %lx ...
> 
> What kind of commit message is this? What?s the exact bug?
Thanks! There are no bugs here, just a different style of code
than the rest. I will drop this.

Xiang
> 
> Jess
> 
> > Signed-off-by: Xiang W <wxjstz at 126.com>
> > ---
> > lib/sbi/sbi_console.c | 1 +
> > 1 file changed, 1 insertion(+)
> > 
> > diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> > index 168dffd..1f0727c 100644
> > --- a/lib/sbi/sbi_console.c
> > +++ b/lib/sbi/sbi_console.c
> > @@ -370,6 +370,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
> > ??? va_arg(args, long), 10, 1,
> > ??? width, flags, '0');
> > }
> > + continue;
> > }
> > if (*format == 'c') {
> > /* char are converted to int then pushed on the stack */
> > -- 
> > 2.39.2
> > 



From wxjstz at 126.com  Thu Jun  8 23:37:21 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 09 Jun 2023 14:37:21 +0800
Subject: [PATCH v5 14/14] lib: sbi: Fix invalid directive print
In-Reply-To: <3E9E84E3-2ED5-4AAC-8560-3D1F37EB9D63@jrtc27.com>
References: <20230609033430.84471-1-wxjstz@126.com>
	 <20230609033643.85014-1-wxjstz@126.com>
	 <3E9E84E3-2ED5-4AAC-8560-3D1F37EB9D63@jrtc27.com>
Message-ID: <673628d32b5c89db0dd2ef9c0aae8b2716a6c756.camel@126.com>

? 2023-06-09???? 05:15 +0100?Jessica Clarke???
> On 9 Jun 2023, at 04:36, Xiang W <wxjstz at 126.com> wrote:
> > 
> > before fix:
> > > printf("%1234"); /* print noting */
> > after fix:
> > > printf("%1234"); /* print %1234 */
> > 
> > Signed-off-by: Xiang W <wxjstz at 126.com>
> 
> Who cares what it does? It?s UB. Going out of your way to make it do a
> specific thing with extra code is a waste of time and obfuscation.
> 
> Turn on -Wformat -Werror=format and get rid of broken code.
Yes the compiler's error detection does catch problems early. But our sbi_printf
implementation is not complete. For example, in the following case:
sbi_printf("... %f...") .

And this patch has very little impact on the code size
befor
size build/lib/sbi/sbi_console.o
   text	   data	    bss	    dec	    hex	filename
   3203	      0	    272	   3475	    d93	build/lib/sbi/sbi_console.o

after
size build/lib/sbi/sbi_console.o
   text	   data	    bss	    dec	    hex	filename
   3205	      0	    272	   3477	    d95	build/lib/sbi/sbi_console.o

Xiang
> 
> Jess
> 
> > ---
> > lib/sbi/sbi_console.c | 10 +++++++---
> > 1 file changed, 7 insertions(+), 3 deletions(-)
> > 
> > diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> > index f7fd761..a4ee1e5 100644
> > --- a/lib/sbi/sbi_console.c
> > +++ b/lib/sbi/sbi_console.c
> > @@ -266,6 +266,7 @@ static void print(struct print_info *info, const char *format, va_list args)
> > {
> > bool flags_done;
> > char scr[2];
> > + const char *format_bak;
> > bool use_tbuf = (!info->out) ? true : false;
> > info->pos = 0;
> > info->pc = 0;
> > @@ -285,6 +286,8 @@ static void print(struct print_info *info, const char *format, va_list args)
> > if (use_tbuf)
> > info->flags |= USED_TBUF;
> > if (*format == '%') {
> > + /* need restore when the directive is invalid */
> > + format_bak = format;
> > ++format;
> > if (*format == '\0')
> > break;
> > @@ -377,10 +380,11 @@ static void print(struct print_info *info, const char *format, va_list args)
> > prints(info, scr);
> > continue;
> > }
> > - } else {
> > -literal:
> > - printc(info, *format);
> > + /* invalid directive */
> > + format = format_bak;
> > }
> > +literal:
> > + printc(info, *format);
> > }
> > 
> > if (use_tbuf && info->pos > 0)
> > -- 
> > 2.39.2
> > 



From jrtc27 at jrtc27.com  Fri Jun  9 00:04:33 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Fri, 9 Jun 2023 08:04:33 +0100
Subject: [PATCH v5 14/14] lib: sbi: Fix invalid directive print
In-Reply-To: <673628d32b5c89db0dd2ef9c0aae8b2716a6c756.camel@126.com>
References: <20230609033430.84471-1-wxjstz@126.com>
 <20230609033643.85014-1-wxjstz@126.com>
 <3E9E84E3-2ED5-4AAC-8560-3D1F37EB9D63@jrtc27.com>
 <673628d32b5c89db0dd2ef9c0aae8b2716a6c756.camel@126.com>
Message-ID: <B9BEFEE9-7A81-423A-BA73-97A32B3A40A9@jrtc27.com>

On 9 Jun 2023, at 07:37, Xiang W <wxjstz at 126.com> wrote:
> 
> ? 2023-06-09???? 05:15 +0100?Jessica Clarke???
>> On 9 Jun 2023, at 04:36, Xiang W <wxjstz at 126.com> wrote:
>>> 
>>> before fix:
>>>> printf("%1234"); /* print noting */
>>> after fix:
>>>> printf("%1234"); /* print %1234 */
>>> 
>>> Signed-off-by: Xiang W <wxjstz at 126.com>
>> 
>> Who cares what it does? It?s UB. Going out of your way to make it do a
>> specific thing with extra code is a waste of time and obfuscation.
>> 
>> Turn on -Wformat -Werror=format and get rid of broken code.
> Yes the compiler's error detection does catch problems early. But our sbi_printf
> implementation is not complete. For example, in the following case:
> sbi_printf("... %f...") .

case ?f': panic("f not implemented");?

> And this patch has very little impact on the code size

I wasn?t talking about the compiled code, I meant the source.

Jess

> befor
> size build/lib/sbi/sbi_console.o
>   text   data    bss    dec    hex filename
>   3203      0    272   3475    d93 build/lib/sbi/sbi_console.o
> 
> after
> size build/lib/sbi/sbi_console.o
>   text   data    bss    dec    hex filename
>   3205      0    272   3477    d95 build/lib/sbi/sbi_console.o
> 
> Xiang
>> 
>> Jess
>> 
>>> ---
>>> lib/sbi/sbi_console.c | 10 +++++++---
>>> 1 file changed, 7 insertions(+), 3 deletions(-)
>>> 
>>> diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
>>> index f7fd761..a4ee1e5 100644
>>> --- a/lib/sbi/sbi_console.c
>>> +++ b/lib/sbi/sbi_console.c
>>> @@ -266,6 +266,7 @@ static void print(struct print_info *info, const char *format, va_list args)
>>> {
>>> bool flags_done;
>>> char scr[2];
>>> + const char *format_bak;
>>> bool use_tbuf = (!info->out) ? true : false;
>>> info->pos = 0;
>>> info->pc = 0;
>>> @@ -285,6 +286,8 @@ static void print(struct print_info *info, const char *format, va_list args)
>>> if (use_tbuf)
>>> info->flags |= USED_TBUF;
>>> if (*format == '%') {
>>> + /* need restore when the directive is invalid */
>>> + format_bak = format;
>>> ++format;
>>> if (*format == '\0')
>>> break;
>>> @@ -377,10 +380,11 @@ static void print(struct print_info *info, const char *format, va_list args)
>>> prints(info, scr);
>>> continue;
>>> }
>>> - } else {
>>> -literal:
>>> - printc(info, *format);
>>> + /* invalid directive */
>>> + format = format_bak;
>>> }
>>> +literal:
>>> + printc(info, *format);
>>> }
>>> 
>>> if (use_tbuf && info->pos > 0)
>>> -- 
>>> 2.39.2
>>> 
> 



From wxjstz at 126.com  Fri Jun  9 01:58:33 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 09 Jun 2023 16:58:33 +0800
Subject: [PATCH v5 14/14] lib: sbi: Fix invalid directive print
In-Reply-To: <B9BEFEE9-7A81-423A-BA73-97A32B3A40A9@jrtc27.com>
References: <20230609033430.84471-1-wxjstz@126.com>
	 <20230609033643.85014-1-wxjstz@126.com>
	 <3E9E84E3-2ED5-4AAC-8560-3D1F37EB9D63@jrtc27.com>
	 <673628d32b5c89db0dd2ef9c0aae8b2716a6c756.camel@126.com>
	 <B9BEFEE9-7A81-423A-BA73-97A32B3A40A9@jrtc27.com>
Message-ID: <578581b38b5bda27fb625090f10d8e84e58a0fd0.camel@126.com>

? 2023-06-09???? 08:04 +0100?Jessica Clarke???
> On 9 Jun 2023, at 07:37, Xiang W <wxjstz at 126.com> wrote:
> > 
> > ? 2023-06-09???? 05:15 +0100?Jessica Clarke???
> > > On 9 Jun 2023, at 04:36, Xiang W <wxjstz at 126.com> wrote:
> > > > 
> > > > before fix:
> > > > > printf("%1234"); /* print noting */
> > > > after fix:
> > > > > printf("%1234"); /* print %1234 */
> > > > 
> > > > Signed-off-by: Xiang W <wxjstz at 126.com>
> > > 
> > > Who cares what it does? It?s UB. Going out of your way to make it do a
> > > specific thing with extra code is a waste of time and obfuscation.
> > > 
> > > Turn on -Wformat -Werror=format and get rid of broken code.
> > Yes the compiler's error detection does catch problems early. But our sbi_printf
> > implementation is not complete. For example, in the following case:
> > sbi_printf("... %f...") .
> 
> case ?f': panic("f not implemented");?
sbi_panic cannot be called directly here, it will cause a deadlock. Also such an
error message is not convenient for error location. Maybe we can drop this patch.

Xiang
> 
> > And this patch has very little impact on the code size
> 
> I wasn?t talking about the compiled code, I meant the source.
> 
> Jess
> 
> > befor
> > size build/lib/sbi/sbi_console.o
> > ? text?? data??? bss??? dec??? hex filename
> > ? 3203????? 0??? 272?? 3475??? d93 build/lib/sbi/sbi_console.o
> > 
> > after
> > size build/lib/sbi/sbi_console.o
> > ? text?? data??? bss??? dec??? hex filename
> > ? 3205????? 0??? 272?? 3477??? d95 build/lib/sbi/sbi_console.o
> > 
> > Xiang
> > > 
> > > Jess
> > > 
> > > > ---
> > > > lib/sbi/sbi_console.c | 10 +++++++---
> > > > 1 file changed, 7 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
> > > > index f7fd761..a4ee1e5 100644
> > > > --- a/lib/sbi/sbi_console.c
> > > > +++ b/lib/sbi/sbi_console.c
> > > > @@ -266,6 +266,7 @@ static void print(struct print_info *info, const char *format, va_list args)
> > > > {
> > > > bool flags_done;
> > > > char scr[2];
> > > > + const char *format_bak;
> > > > bool use_tbuf = (!info->out) ? true : false;
> > > > info->pos = 0;
> > > > info->pc = 0;
> > > > @@ -285,6 +286,8 @@ static void print(struct print_info *info, const char *format, va_list args)
> > > > if (use_tbuf)
> > > > info->flags |= USED_TBUF;
> > > > if (*format == '%') {
> > > > + /* need restore when the directive is invalid */
> > > > + format_bak = format;
> > > > ++format;
> > > > if (*format == '\0')
> > > > break;
> > > > @@ -377,10 +380,11 @@ static void print(struct print_info *info, const char *format, va_list args)
> > > > prints(info, scr);
> > > > continue;
> > > > }
> > > > - } else {
> > > > -literal:
> > > > - printc(info, *format);
> > > > + /* invalid directive */
> > > > + format = format_bak;
> > > > }
> > > > +literal:
> > > > + printc(info, *format);
> > > > }
> > > > 
> > > > if (use_tbuf && info->pos > 0)
> > > > -- 
> > > > 2.39.2
> > > > 
> > 
> 
> 



From apatel at ventanamicro.com  Sat Jun 10 21:08:56 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun, 11 Jun 2023 09:38:56 +0530
Subject: [PATCH 1/2] docs: Add OpenSBI logo and use it in the top-level README.md
In-Reply-To: <20230611040857.51858-1-apatel@ventanamicro.com>
References: <20230611040857.51858-1-apatel@ventanamicro.com>
Message-ID: <20230611040857.51858-2-apatel@ventanamicro.com>

We do have an official OpenSBI logo which was designed few months ago
and was also approved by RISC-V International. Lets add this logo
under docs and also use it in the top-level README.md

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 README.md                               |   2 ++
 docs/riscv_opensbi_logo_final_color.png | Bin 0 -> 7758 bytes
 docs/riscv_opensbi_logo_final_grey.png  | Bin 0 -> 9159 bytes
 3 files changed, 2 insertions(+)
 create mode 100644 docs/riscv_opensbi_logo_final_color.png
 create mode 100644 docs/riscv_opensbi_logo_final_grey.png

diff --git a/README.md b/README.md
index a6bcb0c..bb09fdf 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 RISC-V Open Source Supervisor Binary Interface (OpenSBI)
 ========================================================
 
+![RISC-V OpenSBI](docs/riscv_opensbi_logo_final_color.png)
+
 Copyright and License
 ---------------------
 
diff --git a/docs/riscv_opensbi_logo_final_color.png b/docs/riscv_opensbi_logo_final_color.png
new file mode 100644
index 0000000000000000000000000000000000000000..111478119b5cdda1e9beddd5d779e54e7cb78d0d
GIT binary patch
literal 7758
zcma)>Wl$W=yY|tbfdvAKvp57x&>%sU#U;4A246x5?zW3tupkNU0fGj1hlda#1mDHo
zUCuuL^H#l8r_P7-VS1)(T59I*zWT1~2iH(nc#cnvkA{Z!TuBk4g@%R>Ks^uPK0}ot
zKnD_aL-){90Hak;(C(lrSoSh%GH7VE2?Y0+*r+-lRMF4_4UMSx-wS=vt<(k$jSi^<
zk<sxsJIKLHeKFHA=ypK}>gDI|m1G9>#DbV(Kw$*1XML<-7&YqvhkTqUEqZ{D<hY+Q
z>E!URY-Ha$OP0d#bX?5>VrvSh$V-8*-2AwhOm`i_Y-Aakhx$)h3;&p!8tdy{eAIsm
z+8WFBtJqR^(|x+_I0{^84+Vg68N>fy0TYeBr+YKO_hjiFXx3{&60P$dr$<@$pu9!I
z$pr^0F(|Ti?aY{np(XrLK0*VmVk;6Kd3(IACUjPAGY5#@y56MCQwv`|vamee2x&`0
zu+9rcAw`$N>tiRGFxWvwz4l8iUm`h at G-_v7P@|0&GX^G13ZvdA8~h0r{iaxGAWXLE
z9iOhIeNUU`f;AbTx!>6Z)7TubW1^ir5xy3a9L2RG3<o4raDc)Aa~jgPjMd+Q0bmnZ
zbjI-JNDMHp`*ZAY0D>AHm$6Ui1po|l`cFd}f6<`tr#t;TG<ySO%3iu0zpWq~FLvoE
zqLb6->cZ~Hz!-8YT0x~JAD4c at m>OXk%L~yQ{`S*Zc}J<l_AjV7L4Y{nwc`UODM4BC
zxa!kajG`*mvP;PtF|%hPl^J(+5~(CMslnNX{lhXcq>L at fEQ`&huNNJC*$h~z7(p+H
zz$O3^K9MVa_&6`fz(fvDM3ObN&Gl3RV}muSZxs=S*bNbfG+lcBt#yrHZ&(S(iVIL6
z=*u$AksFVnu<HC9=wS-?@5_KOxw`Vs6&qp~I{z7K*;UElY;~6g*{K`wjQG*z8zg4q
zFx7o6*QwN$>(5ZMJs24=tV<EjQj;EuobVkUvW4Rh&gnRX0Z0>y5(UFlrnymp-0v>h
zZFMm^l#DbihpJZn0r`ak1k5z#Yz~td>wqy at x~-?fQ*}sjpHr{DiD`pa^E1ISC#MfF
za{V`c8zf*DIgCK>e1WT6#0zMi<H(rcnEJx=JLN~Ho34=+lLI+`XY(7!w2eL{L*Mt}
z#}s!WaB`usWlpp2s=DTn3dMbKJy1e9hn0qAf at TEHl@4E$f<LnhZ>;bFDSU+t6LGR%
z-(-^jK%|Lpndbn2N`w2Ve;qB)5$G{U`xU{ZpeR5xR&(09UK=TVOg8 at W{w>&u8&E(6
zG@!4MKCfIhV at a!gtM4rS$LvLYIS_a?&*w^Y)3SRrBn4uL at _sDfKe-YL=-b3RkTbsU
zrJVQ56P~j8cmN7o|2sls^A2$~7JHOllxCZ?0uW($5?(m{ZM=bKA?8bL|8aisK~>^)
zk#g!MDW(Jfsekd)34ZNIZQ}VD`^$A(#BEID$g*Lqojo=6smi^w-_=sYl-6(S;1AUB
z!Jb|8NCbLg>F(W79v6g#i5Nf%-Q=csd`WL{nV)1em+oSF#NFI at ULE^LeNOsh4HBE%
z5KfUu*wWD+kFF|LIYXSH*C{AMMRoH^a`zr=Co`ZBlJ8Z!Tz)4Y5&@zM>T at m%L`Cqn
z2ub9HWvZo7Ye~Ty at 3w~h%(D{;y~~u<AMWNjBt#1eK*@y}rA9=zP;nF3XkFx1t919@
zUev-rB-L{#(s`UZ#5VSiaECq5^%Nm^cUtVoFTwBGQYHdkSGaK=dV?D)ceFp6G~(j%
zV*aEf`IZ>a<z_M2TlX0^S_28==nrgu-GQfQ78BWQ1gt<bS0C*4W&AR&v!A#oXd0zp
z>@L!ck>~O3#xE37rEZkFBn=@b$lIMUPcd8l63mfwZPijOmZv(2X?~~k(eaLNUS&OA
z#i_q$8OJ6e(c<hMp$cxNUiwb=%xzoi7VGCZ2Iq5yz-v7M?cV|Cf- at 0REUi|%+j05k
z>DG1Wicz7{R%5|SR+Cf0Rtw)got6S}bTwOoOyZjT#>9NW6Bk$ip1S1g1{%<cxyQfp
zt^54mPd%&|+%6w at e(|o4yr^}<Jaf8Ox82)i#-|Pkj9ASrzo|pwb+9IXexBEY8JNBw
z-8t$1mXY828GhI&dRJzABVibUZy;v^DL9#tQ9u{IUuml8(B5X4d at Vvi#!TN;<{j*M
z at Gg2SfJj3EcNprQGr$@y$bcu}vZS^|@V{x>z?2|wGy<HY=nmni9u3u(c+7Vu0srbh
z9&}6M0YdsllM=n>9StEW=%PW#vC;o(FDt3CsILk-Bg;b}3#b;-Q{bdOUXk1`VDR(R
z4G&nQ9Y73LOe+Xaqb5gY;=>x_IT^zhWA%guJT1 at 5w#&dkwjXZ-%Oea7bYGg8FDdLx
z{*tG6q4##Zj<V+^e5Dw%#jP6ut6I0c*?!;X<Tkc5I^v3#q$%z%2LofD=q3iK9w`PJ
zO9tV#J4C{J{H2=eK-x{6w+J4_vn-33pyzQn9o!-E{OP%L9i;C9_n6gGai^^7J7dd&
z-`^=hdK?xuzSs~!?J1U<AoXuc%;*_gR3Ugr&ZQ!=7^9T9n*mPx6S_5nY{|;&mdTie
z+kucpu at 7<kNhT1IBtx~ky$P;)os<krjC*5^_kSvzbuFnJu5zy&V`lPl>+IDgiP(iS
z(NJ=*_2*~v#SWeoGMA`si&#SBURH_#GfZ0eZ3sqke<8nIRM(CynI3#C;Bu6CU|%wu
z&-Hra#rzpgF3sawQ!tcTL?J}iebPfenjJ{|Ss`|3zD&kM+qL6XWY~oRBsvkgi;k#$
zYK2_JW(pSSHR8gfFu;B0QU}%!@Ypv;l=e0-#`t^2v@?6Q++xlO5Hoo#2{XNqZJ~jd
zbz7!K`SId$Lh1ww&c=Nj1 at 6d=O4Q_^Z;(EfG8oP<5d}95$QYhFOhub4%Yk4sxyt}>
z(unm!wO^{BTZ#s`p4>Wm5Fi&PCYm-BBZ;bV4q{ZZsM5~J*t4(o3FeiFiPd6P<Z^9z
z<u~p(DHMn90tA&d&xU7R>o%l at WHJq0JIlm|0fd4fKVGrKf7;4U;|Y>kqbHqL{AA4w
z;@+B6+UM79N7L>}Sgu+8I1pvS!M(+<XHbP*_n;BtTr}}{_bhgIt5bu-%~DjV*2a0>
zbza%#4BZWX_m(1nlOEyAY=}L21LuL7x>8!1oz;D^-^IX~+gRHx&z#9(t;v>J_5KVm
zuY!CUjVgW(pZr7~eRO|FJ?}xRCx-l6u at f=V+^4_ahk1_}x2)U99lbp&^u_|<D-vO*
zZ|od(IC0W*+^y6!73{ZQ@{V?z4~Ex*!033mH7p=3^}to-uh7F2rO^g=I}n%WBMzq4
zgnEFtRl~+v;(o;IL~gd(&VG8ntM~`i%eJ-tT}i}NOw}BIEwWKXI2wmNYw{=UcPGxj
z4eIYsjd&4Wgy9?ahOv1Vp%Ia}fk!>5l?kVa2Sk}$(0kFn)73oQnZ{($W1`mAoQ?aw
z=LRMmx+mLzZo{t=_Vf&+2d9so|DuRwqrxA(@rc5nDdPN|+hOIT??V2`fT3*QEnC{r
zEP}^wwIx?mF4_i<dy81Od3B3hDexyb5+ng-tr at BV8o!Z#bJ+f&YM(W9ylsoS)@&@(
zh91 at O4Oio*DM%My4H~_<pw{B;0$$e4+Gj5G^o^1fsaKw+AcM)$>KGtc?ib<cO&D=F
zdM!2=l%!Kbx4cUFnNyd_AziE9`JQ8k?|f^yhGCVzd>w(uzYA+N^iL0ad140o-s)gV
z#pJ%u7I{jfYt5K&#LVkKI|l0HZdCNVypP|d8~(%tB$=-~#&2*d at vlC0-PT~d&e93{
zQFvn^8blOAaN#$ZFiqMpw*9-<?EbLzXvoZQEVtg|Bad at pJLHv6EamfINrQ>J0%?e=
zpKsfSDTC|SgMM}DTdzgW8>7*F7~pIF?^naT1``a>Y&$BmpeeoAey9BN0?!1P73ozd
zROj=n2MDno82qRH<{(<u7y?V`JSf<3Y8HNyE(%-<xH~+p>nR at nIt<Tv at bs_@-RR|9
zu#iO`CRqjl+3>ypup6bMJFZT5(PG=UW3G3#k?PX*EqEO;B-}ujgne}{*I1eP$~z`Q
zV$mNDVnF9=!jx>PA^jm%G$zX6neGC4czs6X%(-j&Cv&(0H~z-)6UkMLFFh$C>WliD
zd1fNN)E!GYC0%=a__?n<si(Gk*8q}cFvf<$)rvLZw<3dTvh%!&?BwZ<ZQ3>dft|%u
zMPtPq!f~wVO9|P~gHekq_R7%@&i-WiRsd54b7x1>qU9c%e^WW?K4U9WE at qmJ*7G4S
z- at dyJ-RLBT{K*ID=rT#!EDlHw)!Q`VEBE81?~d5GXF*SWT7VA;tOV$fJ<LX>-EE3x
zvauNwq4p+84ekEOZB-v8Mtx%0t|+`E7!_FiU~h?zZBi0Amn8I=3B}mYKX?E<G}PX=
z`>OS+I>z>yxdsohI1q+~iIN%>z at WER0N?x%oStsZg;i_aiK913s(3M9Uh#1gvp!FW
zz*UkeV at dv&Emg at OUPU@=F!4??7^N4CEY|-srysq+!+RB&erAl1(!n#M==8SIp`u_w
za-bGzq5;#|)Sn`m%L$8}9 at Jk0<XdV at xH*Qr-?-;wiQiEw!LB<S6}CFbTDF?sJpA|g
zNBjf#SZ6L5pM6l7Y8rKaz1HJ`i2k*7%Hcrtxb+ZXbx=L=*Q?(20sg^t3z^?^dlt85
zo_!PFakc-Z_Jc9deSGx*0p~ms=?QY(=6tzANqQxf%y{cxaC<<$@^jt8=Xb6Y&mLdk
z!=;7$=|@KuN)t(oChzwMWzEH at o6uSHlQ9hRa+QL2_9DQ<H32Ue43T+}M1&p!m3Ugi
zwsIeDiSN*X4gc1p>Gzav9ARdmTkW}fz`;a at FU4B66T@WMiQrP)JShs{rEM2sZ%#T7
znvngG?R2($LSju1>E5fm at 91*K%*?U at qY7@<kju7SZFEg0aVLG9w4q#i3p-0F at Tb$`
z3}S}-fp&!i`s-mXU!{-iyE%6Ppfj^}^~1@^6Xm9&1X^Xh!3kQR-Xp?uEj!o~vi};G
z$o+C_knUhgUtUy_^FsO~)QT)9L?fuCwq(C$E9N1hZl*6lzj|g7z;`p=8rJY7nf$5v
zCmlAA_DVJ_?-*TrReC$&fHaw^DJ7Qb=^4$ZA=i=Xjh<DNNbl_`BL7<b)I)fTXXX5q
zA@|CnTHCpMkZf%?Q1qyg*e1anPx4M&mq3%)B(>t%At1dhFF^2F at X-sf^=9<n%sby7
zONU49n7)3daJz#(44_wcfZLGS2Wf71>*yj;JEr!Jma)6<Re2JfIkptWkR{&}6yFR(
zMQ$$+j-0w14a{5G))W6t1y2TKzrz<4=0*zayOqR`;$l!U566s>>2u#beilM_d36+E
z^IBuVt|y?~eD{x}lRN~>$M at cJ%^|2sfj#MaSdH0FQ~EFKTXndH7ll^0dUWEj(+Jc}
zvj6eEzeyNTwSFm;TdzvcxE9}H<KkAkA>G<+L67kPcF2r-Jx=n)L}A|A{xeZ|n)bdk
zW^O^LOU^BAR09D>?^RW>#;!Gi=CSFT=+phlO;&#+61pIeCv*O`+fmVO0L-u*z7Y~L
zOXS}u032vdpPF2Xwc$zR2r^z$hzaVmx-zlD>c+tPC at Q6XOcUhZzAqG#a(6Yoth@^r
zy3H?O&t8fm=6VLqn5IIzH^2U=Zf;)pLmAC$-&j7-)yJL2l%uw*$&3Fjd at HNU%%Wz0
z{~rQH{zJsIsK`J|_N^i1TUTtXYC?>*S}Zkbg9*NFI>X6vW`vq0`)Xh4ao_3VGy94U
zYea`S5 at _nBJ3+M8G})NVLv9b_ST3>JCulY5P!f<E2FCicSg+G;?`nqo?)f{1>2jII
ztS-`M^?{I9UUM%t1GogBL{E=@wLx0&qM0PYgvkjTYtx?_fZivv2zBwfR|;*V^EbcV
zHiOJtcgsb6{XWx=Ifq99=I{B2gDwO6Ow!B|YbEX4<#d10dbwa=_F>s<-Vp<NEZX(C
zE=Hg$>vlCszd^iN63$HyssT8Tb#<%#3R=F+z*S;#GNo)c{4zoqO|~*Ov9GXiyNE5`
zFSM~RVITv*>yv+M`KHh_?6B!-8N0lNbM1#~`c$oeG}HfRx07?xA32+-xoO8OUn~rp
zu!=iuVn4jG*z9a>3j)uUkZA{<YR|F7#)Mu0<2KH<SCCz~QFJZx@`Z>ih3-2A(DH%P
zSAvwa?Gnq@`ihjQ_19u2Qga*B1|hAY7)>?7R at msp!n|hLu-kd8wntI1AQ}rjC1QW?
zG1_s;ybMOF9K)V7B-5<1DlG4fCwV at oiz=u8mlQ)~NJ+;-V9#0QvL=i1CdkanZffl;
z7!8phMi9YizQ|%hCtd$*JT;~h%0u50jx@|r<=XP1;SlIOe9ANgspkPV`K_pZRn`q>
z at Zq_o@-h-IvhZF`d5YN2o|~8IWyH~9IS)NsuZ$mPFGPW#y1+8reZyl3KnmQNAIp_P
zIs`17&ElP%tA(Fl8r7&CHVeK!M4Mw)9-ruIeS^{P1~2=OvPH_wCde0C5=V8#iVYjc
zAt}q=1rBLO^r!-BmOqHeiVn4&?Y(Qm95f!)JEhFLmQ^MiNfXVuP<qx(?MwFf!_*!V
zHpF}qqpAXn{^<oBw}`OZrJSW*WarZCHhpWD{_F|p74(ClIk4tDHW!FkpykyWAgN!v
zNg8`G`g1AAhRY{*Y=?B|NhDukO=<pvx>5-lO5XHKPHjicKV at L?37|Jap=uW6-C`l7
zZI at l<4Ti6p<$X1V_gG<PU1|`Gh4-8Ndt0M=7!Bf5b>h|`@V&;+(<7(bAw9BYGHjk;
zI}up~JIoJchXEw$%vmq#nt?xyx&R7w?Ac)Us&{!X=@kNbBp9^+>W0>fOKJ69d{vwn
z9;PDjcgzOW#&RyP8qc=1 at VYu+8AC~TON?rpHB+k($n29XmT5AVh93plJAF#-$L<E)
zZ06W7DHf(Y+Nz73eJ1CkT$8GP*wkUqWoHm5My8)3T|+=7+yD&7bq+?190R99Y>$J3
z&^^+oGB at wRrP(>h7J4#oK%m$6>n!6oFqynxRhD7FJ!^-?)`L`g*X*C_&rQQ&A&l=^
z&w_#$v%<f!AgB}#>I6iS(98G=F*BZ`-iTs9^{PWaXo@^@#thKURwb-cvpA=T-Vw3C
zoPkLOpz~{q>}Kq18gBj4L8aIc9(hse1EajOszp|4>lqRpWTosG3WGQaYE;qeaUpH`
z`s1-!3zT)P{|>L4Ktf<$O$zmrm*7E<UODh%l;+n<1rdL4WBcw8zP`tS$5O|Ei3#~Y
zvNk^2!87Cy)Ex{d&~BwncUV1>t}_tS<i33SEza7TFsNYCOfI%3fs$NO)?e?|12g|n
z;X$ntaJ_WnURU(9xytlqo9RoxI*Z8e%1<~<_BM1yVCNocUJaXWqm8Kd)r&<9?%zp}
z`^jCep5Of`v~}0ZmfYbcKmG}whP8iX{9VRf?i at AmwbAc`13k1w<d2A=)`dD#VaOh4
zzB)8nZTEBVD#mrUu23V at X8=h>gJLrJB$X)=i_%spi{!3dl&<7SqMa1Le1c|%pGsdr
zqw*41LSI5PKAayER~hjdot=F1<V0>2;(?)R$wJcdfH*dh_rbSYwdsr4XQ89<lK5R<
z5o>%bY9aBMz~CiP(l;TvCd5b}G=D|@u>WgAdDWAtWy~eSt~!xD$WL7}A$rhO8 at XJY
zH=Gt!?-qyuYsu<9VnJ>&RGWzw4?Z2|lYe+VZ^L79%zR6)Q57s?H7iunAAG2=&OGbi
z(G=$0BrHjCq^FDfh`c37gwmVi%V|Q)I4X^#?FFpX#F4cXI0pcM!S57aCVCa^@+BX+
zDyQwTUfv$)4(3qYe1pADVxUmiGaBxEkHLQDV;T=<y0{rAJqmK3=Y8E^Rgm%4r$w0l
zi9PM?Cp~#<hqIHzDKcm|pkM5D<s`aKp~Is5g?i^!sgE>}cMNmaFD at XjXxF|*+0*ZM
zel<v)zC-jdAg6rLp|mgH9f#!p+(pLa{KGoU3}Q3si>j3P3$5yvY0fndrL^rUA%{P9
zCpEY2 at tyzpDy@Pq8or|(#oZYX)Cm!PRiWp=zZI#S>%$jV77^xGZZ}%Yjx`W*Lc<Ik
zP{I>u9LF=I1S<|8yeZh`ytYcP!F5Tg811NBIlOs5MzpgCJ3qm?5G-s28dfi2!i`$5
z`8fUpU=@|FJ^uXp4XaV817R_RVsZLe2_}mNYf4lI?F)7SLbBvIta4P6n`{@VGm%G>
zyfll>ODOEi#-jf!F62G0Dt-f>Z(RUIWTJB)$|kY1JtuELjUt?SMh5<+usU*s$M}fK
z!`-Mb%S?s7<ClFWky|7 at lcQ$~Uq|EE8f at sa>~Bj(x%q_p95y_JjOdXKufh{!BmRf4
z{)h)7g>(I!_o|m}#ATETp}=LNnwSkc=#Q>4ZCDvjgig;c{ci7)LWhSVC{h=_#vTrD
z!q=Jpe6rr1M)s$gtG&3A at G82zTbPV(T8w8-6KefP<8 at QBP?$iW*lZ*$xU6i&FdtO8
z!*dw;DVy>l<qM?$o!c*AWh0YmV at YMjW5c>j6Bp~Mzi&?#bSqbuG{xfw4@#$w?$gyM
z6d`c^)~p=4I@|F at R@uG;GrFQGgefXVFQEbdm6uQG;2(j;$bv)V!+e(~4JC9gV|}y&
z+Fm>7kTsfb^=yAv;yYH8rrtY4nsGOp*Ao=>oO*vN*SRFULH^R3A+6On1J`9X%>iS2
zg=q>cPs*EIDsM$R6ZZbQU%iz?&T#5#%8qw`ceVZZ>Nn;nbCgZJX}kVbyxse2np!9A
zH{dlTX2>Xcv at u4Nmgl=lgVyQ5rpty_v0;=WTKLsA%-K-;pArAs3T!bI`ihFt;*#r^
zpo`}|?tIj|s-gU(U<BpgyM5PSJqw^TGc=CT1`sndOIWsA5iD56N&4MiPj6 at yQM`n#
zYOYCtSOFxD6Yl#MsB*8c`3;y<NSe*|dYjv|U#x9u(RSeD{`1}W8CM^-hS&yz&t{aC
zJxEruQNZsP|Lfw9>HGa*Nbf~l6Jy`K-pLv4fCUrrk+lE at I<8%_*NPlgi4rX39oxKY
z&zG3~=8_%t=Byl)Hpca2(G6&KthChYEeK{MekIci&v at nCx{Y#)>&J*=h_Flg<+kWw
zO!Jz5cj>F599spyp${}{f at U}dINyJq at Si`UU7>gpy>WlaK(VzoSCL$nt at LeA&s$5v
zZ*JkQ+uMxterFXy3;ZVRw83zKCZ_<fqD0O9(fxxiUKyzwAE=O>2Lq#~lecj=#We0T
zSr#$x;5JOp*vI2F(J9vL>0lK9Pu{A-ixtxhj;KqWDz4qv<r*`U0$-;8r4Z$v+l(j)
zQiIy#GG2BeG9G&}uue2K3O at 9Xj402a#MR^BzG*J;g-g<7koY(Sz=biVt7_EgS;PO3
zcp3{I=^u^OLTZ9kHkRtPxEwqztvG2eSG6uo*_=~EoO&Elx)ruh0v_vfCfFSy)hu_^
zm&|NDFvyaV4xXRzg2gNrM-R<C8>o6FjjJh>O!=Ygyj$z}_^IOJ{qQ>!zmcA=$@G{>
zf2I8i`85&n3#$*q)26uR8%bHEsbS_NimB;J2T$$C(!&(zdQz-vUcTID2XHB6-?Fmc
zLa;Fipq9_+xWketL2*Uy=8)kphgZ%qR45Xq*|t3P1r;Ye5ne~armRDS&sEy|^3rIe
z6Q|&kTrIFq$~q$$7Ox73=b&N*)pj-D&CRKej=H^-p=V;TheN0 at 6{vg9dh%C^GeNYP
z{Cd*)T`%FV0wkpQ<RvT9?Pi1XTMbPk1JQ_Z8=ke}9p+s*D!iy(znRNHrqruOCj6CQ
zmMIu361(sDZCv~KtBU_-e=7IXd1}{Y6Yo%D;r}DN{|oEG-~>g({_s^=)fxi_J=&bJ
zkjQIirbLt%{bHeqxnew0G#6<*{X%Ncp3KmE%vyfum`XfVvDDxbSq+yB!aLq=;$$9d
zVGW8aiMT=3CDk01&!DhlU8W-SfIUHoh74DI5vlA40(gy9L|kNwp>YUOv_o`|>^}fC
z*|c!is+bz-cz9Cg+Mcz0?SHetQx?zuAG9hKejT*C;j<kCWqpfcz-UTx>X2%%Md*J4
D0r2r2

literal 0
HcmV?d00001

diff --git a/docs/riscv_opensbi_logo_final_grey.png b/docs/riscv_opensbi_logo_final_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..a370f4119d6b4b1b766df3ddf539a4b6c5853577
GIT binary patch
literal 9159
zcmZ8{byOTb)Hbrf;)}a1u0_k at EU>^*pcH7aQnXkpR-m}sV#Qrbf#U9z;tq=yE5*II
zYmsk%?|Z&~-Z^J7lT2>rCg<knd2$o+>ZJ-H9xWak8XBQ09Hxzih7Ll#4+61KDKn^j
z1NA_6(N<AFs~n@>MP&fi@*47JXf?6;_hwkAJgyVmzy%GBsOP^MeZaB!JsKLTkt$67
zwTJOxwrUc6U-|%My+B(@gR7mrTUi71L>NGUI+~FBU?*I2`*w8!Y3q>Ff<*S!$&6oF
z`OtptFFNh=lT8<rrWOPSLuc`7LAmeX7`Wh}KP14kdnN0n+FFsi+LZEA<lWP9)ZCjH
zisU!xG*36}0xa!<3P5lO=zkK1PKL*oyicimy0J2%#~xdqzk8;O+xMDk{T6gyqwih~
zfA!o#uW}*@jJht=^E*l&`570mSLVmNA4Pd?QDt;CtoN<k?!Jn&wCb*+T)+?*$>erw
zwB}!_hfuhD(~*4X(wF_X!gA_cWvbBM^(4r@@yd6`(b9L){K}jC#clAGXI1aFyGgeo
zrOS<yCcjE9b5JsVQdslK^1<B&yerpmx!s?7MpMP;!AJ{6#o@@7-l|aloHTAWA1o99
zmW{bW1%u^N6aWU)5+MbFVWV(p2<SO0I*Gz`^#3VLOx>+V&KmtqR(dpnc#C|X+*!Hx
z=Oww8ozV>6Q_*qs-Nwp3d&(h at c2N6c00rTs$kcrj;$lo<tO_U$jLKUJ>A}T~ZSwxk
zFOtzv7EsORRi_8X2 at imC!8kX1dmendc<s%S>+=KRYH-n=Ti8a at ge<~#kB<eCcc+RL
z=9WyrXZ at G^bECKCJBKTpvbViP%}!mik9%c<p=}5tM$nrxJ7XL6Ll)*{9!(D{HH$1q
zgbklz{UD!7yO9D|GANN#GlN+6rZY>@jYky at 0=*b9%KQuhg#-iYUqW9n)9=q#)UAVI
zML}r?ORaN@&CaYZ)IlK9=N8GL*}C|^%Hi0b+9~TA-QZpiP=ftJ<L&q`^TI#PwqLHP
zRzXiq6sB(X4SHg~t!1OA1jODpeiW*+9=|dnQGjY{#<u)BY90NqmWoW~)w|c at zo-vE
zckr?l5D<;h#RaAeX#T84%AOl^__gsTa%h~PghIY0eviqLaOwB&6Q1MUZ|k0LoHA#r
z0D;UIHhMR at aF|4UdU_s3z%Ww%zxr&=&(YJELfJp{3ZzecL|+?tDAF5VOc`MGMiLMa
z-HnHUY at twWY;5FYzRH6hpFRt#G5Fc1FI2S!^B89)#$6cPfm`5HP at Y)YEXXVZM3%mn
zT!E^QKr>1XT4%I$kw&-=+LPqTg5nTqKrqHSI34><COb3o_=c&<)Yt$B05dmqd)zR%
z*YB(QfJ=*Vyff0^Hm+8YdQO&pYstv+I4j&i;<mFL3*v#BtEP at axl$tc1a`(en`Z9}
zZ=a{f2dlZtcUI#$GTW<N!P}btcZul|E`{l0_8GpK<OpCTvf^#iz23)g4Z-Ikyafgr
z+E%`x>&}B0L5WT`CuS~xC%{tK*MA!98plF#M~N1IlhU$J_b%sWBLbOZoG;VHW&a`D
zullG=^!L{X<5>%vn&w>HRjT;=V!#~T<Tq&PhTu_~nCPEL=1fT8rFz at MC%%lSBF#+H
zUk#rtd2-*l!!jj2ojG42e%86{ygZ*&VY(gfSCpcrp@}$z at 4mO?1oMWNe&Fc&F**oW
zKB))jOeaEZP5d9+&UcHx-c>DbZ;xhfH_RE=1+l;;O|gznHwGT8Cry*-r9LD5DG6)(
zCNk1%PvlvL455M)!+?TccPZ{GzL5KkfiCY5E?O!9;|nJCo=;C~HWtmof#Pe;p`|e_
zcIaKc+*_BXo8L*leJh41s7r%;o4?SW=JJbWm17lrOt#OMX=vt7cIsjWN5V`@zCLlK
z8`N3d#;zOGm at EBG5U`8-uMutorf1x**nj-^aj$YJn8gm8>^!8Vr9JzqBw{(7^g2=C
zwmgn5Q4O6tU88_WU6B at IJ(R%y$O?|^>yM$c&@o`fzFu-S*_+w>CYGv3Rro%zfFf?D
zOpkLLW6kBLWry)89n@#O-W&1RnfqFNiULGfPQ;hUnd8yTr(d1B&Kw;4ncTzithbDI
z$V<|CcR|FHF9sh|y>PzG`??v-&ll@`+%~74BR%i01SG-1%`oxWWq(Syk0OLnXK*lU
z%3LO04wVKvJ45RG2&C7!6cDZxemS1oG*9W@*A8Xus0v{X>*&*6 at AKi(AvSU-5e3Ay
zwp!6Uew4G5#8JSTNqR6g%WwKkk|m0vU at 2TIcbr@t%tir*`I(U?hgKJ;z~KEF;hLnN
zWp#F*rzX8&Z4x}NBzFC(KwA)4OF1Fn#EQqV7N`P@=bb>es!M4RamMJ*^r-7q1g=4;
zhQ-=q>8Px5WslV6GxyhU<Zc3=;PnZ(?tYe5FK-tQ{ErJH{+)Wd94$(?JlqkU-yQ-)
zHI%NE8t>0iJ1&@>1H>*Ky{nQMC#Jd7!%zEC-P6<{9GRg};iEq;>5!Oj8`B8sW;2(M
zDp$LC!Fi?wQm_J8R=`PNp?xf82C;e9kErEk**aH`Ug^8v8&(@_`=iq(Z0D5b^r>y#
z0WZ>@_2L2@*GFHIGISOUC5}$~BB}FRlAJm;U{wG>aeix^?OYiIuu+9UbW~Y>f#ZtZ
zhbFXJPio54B=kZ&yLdNsETN&l2gLc||2sS)=>^DZlD_XnMRVnb4ZqaW^WKbO1vBeC
z-%_nIh4+Suc<7`gS>^NmS=OhPX>s0AE?op|COXZRAiPiR$D|TBb`F%zmc4P1j}JK7
zJ70^jmZ;`QX+v#2yi)@<ldQk`ioJQ%hw>Q_QG6E5ggEBVFfdf4&F`IUsafswR;BGj
z`W<T~xm-=&tIc90ED}aEZtcyKiM6<9bTdk&3Yau*9n9BRt+e}Yx9sH9Em)Y^_D(J>
zStu)qjfUXOM*cN&wRYudmIDr+Zg7$+y&qfjwEA;#^PsO}&5FKjTK#g_%dSeoiP>*h
zGuArvqUg6WbQ1$*K;-;8R6}w8DH=#sf2zJ-)kO7`a at T*!i0*G&_j$qqi}_ob;bbt{
z!rVgYkf^&x_Bf$UV9I%v$M0%-J2rwCpMGR|PMm0ajk_E7xcwI>PJNaMEEt~*!YA$A
z4X6?oGn!p`K2`p%Zq}dUQ+M;$y|X)(V<ce~Vm;79aFGs67ydoMdZt at h)nyxb`8DF_
zuivc-o0J?GeHwfg93S$n@>yW`+r$}``T167<Q4a$Gz4?D5*^gU7~SO8T<!N~YUiPP
zwCI&l6tP33u~}Vz#8KUuM5c=jsAo&g_<yG3i?y4pOn=+7M-`_^#+i{^rkmk;j(x8O
zd-=br_6R?Ab#?s~A4o3K+xu*W$VV+XX`%R(&!ux%gcV0_m4wU37#JDF9v&Xz&xK`M
zJ*To{TxR`srOvlUh02b8jJ#AQ;}6C+(kN-plGD(GT83;oRKXb7N)Td2RaN7B?|z7W
z)}Fhhn>*}o^GXw3dnqC;Y<?b%FbBV_RW$3hG&Sw~xcqY-8ELQ|wD9Tfg4<>H)1mRf
z`(yDD6_wFECAG~T<e+zxM3`#9n+j#R6~c649|c9MddIQbJkNDp_NKXA_I2++EWNn6
z9v4>331y8`opn&=J}c}MirLcZxJzyT{hh%L`0QSkDT?$)U23>t>&>^jMW2(8{^1bc
zRlOd+*quW55X-#x5;jz0<;jnJ&qB({43Mv3Ls%4m?G<HjyKv91P-eF`WB15A(-p_>
z`9^Q4LGmiC$ziE>#pJz8Hl3P~Q#Xfp(jfE$EtT at f?E*cm%^z)C-AzA_yQKL#cgNB7
zF6XeYl(g?XJv9St-zFCvQL8AKeI&||_HIt5RnNzyjy(u}UP%{E6=^&lN#PgKDeAWt
zW^Gg;X+h(k`1HsUL<cR;%lW2TSZdPjw2Xo{10Ppvda^p4CZ9Afk!eCp<p!-BVn=}s
zZfo6G=gZ#52E4FMY**;WZPXwNwIKf;cR1>h>y9MzrjFL+hmRh;YemNQuu+sc4&QZS
z;UhacbDus+Bl^E7h96vb#7os at bri>GeY`$en$3W3mI;h*sZq5l-?z^{Zf9<Pr!o<h
zazCum9jFM|98T{1lP2Zfm~Ag<Iehc{d8fOS$4Tz(YA`X%%9d5hU=$Jo{hoIhwsd-M
z(s%(GbcyRzmF>f(>vS?>#rE6z8@~4qopFbMYbSp<<5Z5I at Zl(GfhDW!jA{&vr{>=g
z;OSMoI$GL~7_ at y#K3(+Ofr*Iz?B+|8lbb14r at hId7)j0Sy2ZcO>sMS1KBi2qhu6!f
ztIU3S%u~daaav`dqlyTgY2wwZ6s at zG=@7#@O%o|v;iI9A%$^FobYAbpZLLWjWH&-h
zoMV7ZIU9Vr#l<=gaWT3FxnAj*=eQ{ee|(g!`+WEVrJgRyg7Pa5zE7bk=k7es1jrqD
zWVoxF+X6sNr)V~XfneXF#M+asqV{1kQS(2z#*5>wB+_YJQD`IKU!>ru*?E at jPQ-R~
zuc+8#HB}h%Mw5GhkoKLJd6<f_#s2!s!<CK|Ls(u~0SPGH;tPY+hfuaJHGLlV$dg~}
zVvZ_?cV6Bf7g?Wy_5soHREs=X>TJwd;Sa|8E}xDTTYiT{BNlzfX)~Kx38$n}cXGUs
zgzBs=|5ZhYw=k+ZBzln3;lgn`zqlZPvrzi?swVB`p}YJ0s`SfBA5#eUh3a;YF}_T7
z8n_uB1{-hSP)R`VMn%)|i;vS&g&GjzkA9s5$f%VQ+qIxuD_7T+m_S%yUyl!QP;;&9
zAEIaQ=Sr>TQ9?FI1W<mIjU;`3#=b6DBS%{H_O#wsXY_1qq++7ic^gTy|13fwck6y#
z3;_(((CzNm;2cm&mvZb}Y_iRNXRvQtoC=U{e)f}-;OoQb0Mpxj#j=n1IEE+*^N+3}
zq3!^Q#BD2NHpC_ at +|k;u$@>SN(R(J9z&DDEtRKStwSW`oC<kaE|Ar&o_hv2pk#_ at Z
zy;u6CY;-tz<nZ<7bGzA$-Kl&sK~|U#W7I9|n>-cDUsGqs2FIrtTyi(_ at amR}W{Nqe
z8(Df^9T?b6+9ccW#BX*ZFcf>ND+pK;>aDQX{vJh)m%cPjiMDBA6CrI0HrO>B6L1K=
zbUIlDKN+~0I>)_>2EWzv5PZ{+Ws;=$>hfewaeK*qrGf`-*gKX%%Ial~H22*1n_Ntk
zTwYhU834<Ujh`<r|BLQCWk%%4?Zyt at N|@>1^@BELU<I~4A3N-P$jkbNsQhbG-xOeZ
zTGaoS=pn|yANqW>CqMb2zSu}~fbtwBF#fANO(2OHIt4_AJk>BqV!y_f`7HO5+Ng+T
zkEja=kEg_thI~7Ip;0S=0iWhq8Sh3EVT1fffP8&@uiPememh0l^?op}jDI^S<$LEk
zwXk4UHNLu<n=Wh_Ihv~+=5B0KXQeUkX2D)FqNJ at RoS!aY{bzhjKZ=sS*7Mab=w82!
z_to!>I`Ujy@$DaO`^adT$rjx`c2TkhWBvCd1;0!dtQjZMod-fTNUD0R=PD9fkF8kj
z8ky-A)ulckRJTr>w0Sjr)M0-n>M7Xlxs=1cSZ(l5S||sl<DdF)|N9LldpuaBijxo{
z3p9W8u0|}}4k3O*8{48QBO~*@U<`=g0{@`F36=SjH!)u=9;Z=@Ldxce%2LMOhYeu|
zmm}73JZ49We_zL6DiAGVpOxx?VzqxQG&^RMZQVaB8I2NXxA86$l_7!fLkJ-lkZ*&G
zuzxX-<!VA%+a_ro^PbDistpu9NUwNg=ijJ&*LpDg{tN3clz)JKCpOW5-0GViB6zyd
z`2(Vy57Zl+z4CMtE;sEu*+NqT{~LiKb at zHo`SRtqX{pcNotc!x*iIE1KwS5xYes+8
zFgt72yr*ptPAfmtm(XW%)<u6}C4SKsk>q5iTV-tju7S at c4r@K-{0Yfx8N+AWMTb7k
z<oO-UDrC?L1ra|J(}hj!b+T;+5fBolv#X`(e@(ysbZ%ZUQ5Gr^u9+b^6dfI{@Bdnq
z((Ch80j^`st~tZ`&bUAeVKa9xl at n*Rba!60)0#pnFC(FJ<jT|IwPlNO%j3_l`YPnj
zTJ-o3ZZ2$}CLAW83BRfjYma!=w*Qu|+pYVm=BH^e%_QWWjfju*#BaKOleBM>k`szO
zTxg0VBlar(kJd&8;y0g4Li!>pc#-by=L{}$@3s>6ZwMUNJ||GcV8s(VR>w3?L0gE7
zsHj|WzX`l;L`t6xvZCCMsN1VLU4+b{|I@=&JJ1l_$3!wKXiEyWGD%a1=V)v^v$lXd
z$DtmpJCq&or8XVTHiyGt53$@q2Pv_v`0mXh?w%7%&*+GSY-SGIut|~ipP!y}hq$|a
zz&o>FKf)A(nODODNY;u{E4~YzNVUZ8f+dJ#M7wbT_kwG;L at 3BpH=s%eDzqM`-xBGm
zE+IeSaA2sx`!aOubXooDW{EyLr>#{g+sx}^Rerx+ye!t`=jTJie-f%EZ{3fV?Pc%&
zvOZB*V1<uXWZ{z)8shiLLm43A)YNU)%ig2EzN;O2R)&c+LTQ(m6BS1<gSX6WT?u*(
zn22blAs33oGD&+utYV_lz2LMdGQIGyF~YmM{i=a0C_QF8GyvHBiz`^F{Zyj&z0ExW
zKPLX#g|&5A4EM{3#^{cYQ`^aT at GRx=8npvCI#u8Xn8z8yyAy-0vB-tz2O0R&<oH!a
zHYQ*NgPxeAGmkkLT;)Q<`@krRBmYSudhk1mR3+vdhYjwlShJgEi?h}s)jSg3-i8E^
z*2x^xe3gq`v{D9!wWd#Bg1VMbXu}ZQLF^kfkWop|_P$w*Y_*^8O1P6y>DWL+Ffubz
zva4SiGiEQnX9Bcq*<I*KFY33B2D=T0c#s20WUgi_-j at A&7MRIIB7gH2Ybx3`ME<~O
zi-#fccyM&6+EYA-Jj{;lV at Q?=j7MXF4j&^m=?;POol at -?E`YiV1`A?-J!8m}tqcYL
z_Jea6I(``br3kwGySumu;NX9LhMgxr1x<v7SWI!Hb81DQ1&}orui2K91 at +-m@|~EJ
zFpQCO;6ONW%ad~P<z)awR7nB06Qy{Hto`48?skht=Q<uQYgON02K+YXX5JI%xUcm+
z;NyoD*V58(leR<$I$_HGJE&{?hSoN9a#B6t?40jwOz1<|CjD3ytlVfhLb-5`PMDsP
z9ma&kqIiG>X5msHR%P%q*jwwt=?h>?$3|WgUKK7*1Dsn*f=~R~@mVQFxsac7*CsPr
z3q?1pxh9=xSPG2EMQKAKk7+_SMl+s|5DA(0xAtplYAgb;+5c8LA4$ASP+JG^5AUtg
zH+zr_YzZ9M at N@W!V{79ZX|BJ$zxuF5#Wlf2fXNx%{i>8P)VY4^lOHEz0G9TC-?y6o
z$b-Kawl16<(i8am<DdE=pF=y7I>qRhpk`bWTnAX*{Td at RlZ5oTB0bg|JCHEqZsn#Q
zQogm?i)mx(<BpNAa=#6!km^5n21(`CSj-fJ9!G5T9fS30?w5V2zJ!_rV#x>&`sEqM
zG+zf7d^=r`U_ywJVfg=BSTUp`nk>1Pj|n^8TP!3}8M(DX*AW{k|IBO{jkj7fAg`zh
zpRF=6*(M@^<QBP}Vm_LW;dt9X3`wlz0c)+GVheF$Ams~oDpsJbiU(W-*nw^bzVQc?
zYO`{Rk4UUuzsAeK*a<xEs=uZ(_UP*8%3x;$q&rt- at Eh3^7=l`|<hXqvsf=&ws-|Tk
z2xukn6fp;2t`j;FWE-;67&6R|m|*2@>$PWSlo2iz^har;kuOZaX8b1-(Qt7Pm6sbH
z#LfeN4ne<;G_}kK+Ksj(3t0(E4v}CCvtW59j~}}7+E)45EXIH{OVmssTxCKsGRQ at F
z{0n=KW$@bp)O_W07LSTKj(AH63Bg};(dX57^dVY-{Ix3l7NcUe7swba<gl0#X=nDw
zPeLxHJ23Y(EiNKBGZmX8BrHZC2OuN+Ov%tgE(Jb;_w5wrqiHQX$aA%vvP_YAGp2#7
zj52qB^S4`99xC0&LFVRg#H$l}Ebv%xrp{<XzvL!$?`qy~Q~M>q)JpIe%R%jg8S`qE
zoEc41mfTCIhtBQmQL!M#?3}^CfZV$Vr~t|GLNZ;6wtDC_+hvHB`1wkp$Bg7JZNkbT
z$LCrd$u5Y?pas~^zeAi~>(Nz|jX+7&yh^Vm`ED+uDqYcfU#OlF22iV4Wb1IoEpTZG
zo<sypc)Pf~!I$x`X6%NtYHk$mV3j{#EYJ<GS#@~ahI9yx%RT*+nUkNA#Z&hU(;^|a
zipQ?Psv%j7QpRU-z#Hgp!!v~HJ2VR?FP0MpHp|Z^q!dsCb>ZnP+Qc!@fu?~ITtUwG
zun>HWPN6XXQIE!8R at AB>2ZXdTBFY~PqA8BOzD|3QW1Bk(auolxiFg{;KaP5<C;;#2
zjKu3_wSlGGrd?-s7^=O#$IKwXG}C5O!vJ}VL3YrE at PFj03cBSqYdJ+qIOC2POuJRO
zag+v+Z)O3oB0Z=n9e?*l<mU>3o^=ZRJnOhh*IcBLx25)N at tyfYU_?OqP9iG+B%_Hb
z!y1$BNl3)0uA0w-a`|nx83tw0D%Cg<Af&;i50sc|gAQS7bI&08_8IG3PP{gR8bIg4
zUc5j684nC7pok>GVBnfPx;NUaF16qWUED1l`|07qmD6)X;j~sxV1|j@)9|S=Xu*zE
znvg0?TvmoQsvAUt6KLqAvJ(kLT-<kANL@#Qk<w9ckk{vsq}{V*Ke8iCA%s(Oq)XE5
za5?2sX0 at p^pJXag!TQm?Dr%!_!AnA}T_|cNh-Dq4RG{r5A$xL{mcMEv%t=x9deOzQ
zr?b<#`Yb^eHq%LXy`AZpf!cVV_rxE&*y8Bjns0F_%4VRUZ^yEF8>WND%mvg3(bA-l
z<_)rm(CSpLol>U;S*-C0l0=ovk4v9NXNSTU(Y5S3n~9M3mU-0X-7eNg=iY)(BpQ`q
zO7n^A&IeW6k`jta;<`_}prCWPYJwKst_T+iY>M(ia(9UiOta48 at 8MO``F&lZ2r2SZ
zb)ZluDI#;&n7^5yK8jj}x}28w%|t^fm67l|mnb$ZkNHL~7alGC3Spp2&wLi<n8*tM
z7}hsuo$w)>%C6AVvpLMKs<~wG?m~p^YBH+Hyj|qJVOc%8+}TP*i9C>>Z9B{JJ at o~F
zf|oyjP1unyA{LWI2Vwp0>}Z3uX<Vmh4s1pu4u6y{YMZ_E^^WSQb*pXGdoe*Y+eUzQ
zB3?EyQEor^+$l>^J5jB5bo$r^Wdj6Gm-QE_tzYIPC*J!c#HJ<aEOZ3T+Yt(|D4R6c
zA143%)9FbE2e<>sDEH*zSd>{;^sG2OoXbOwm4!_Tk4Ro65K+yz6^O%Fe6uVLB5J48
z8IW+u*LbWyX?=&enKhMvo?WU+F(~0==MuCYPm#rY6oCqT2#Ad2a=kzNZJF|l3ooRn
zBGN6Y^VMf6 at _a345#i}5)!5$!E%JF`&e_bSwH9wC#Q(-DMr-Cw!Ea>gapX-0Q|6{R
z-TT;ATYs$bR5?eRI*!;y)2~qqMJm#Vi{lNrtnhO&`Vj5l>T!=%tV*4|qZ#|G%Wy=j
z5Q9Y;tqNHC_iK>ErJc&jPvYrfR{xz3WZUqhb at 4#ck8ExT>*uXZFN5H5%S-i>^}2kF
z^q;9KUB?l4X+ at zcI~>W*>g^`lD!mPTkx^1qwrdbEp^{HMWO!S$*uMz!%$XOV>aKXi
zZFrL}|A#WY`TxY}a7-Yin8r0g!pt%;b={o#C+<|JMkAfVvN<zgAfeF>s3;hR#;?|c
zdxJYkghIQxis~UyJ|PmdEUaI%Be$98`P|4bbymhsAez?gDux_5@?{2dDM+F7zwJNN
ztTEr|aK}L67hAo>F{0ik5hPYXV08Zx$9_HR3bthg(%F&W*di3a?szgQY$jv(K^H$g
ze!YuTV`~w#Z_6?P#!K`W|ED3I^p_7W`nK+EgNk1(!}XD*ZgB-HAzXsAp{VGe`V;`x
z>VvB#{XP(=^(tf1)|#LBdvOIH2%MoNPV7i2ssa7=nC7L^i>u}Ot1<pnQTC8)bh$`E
zP2Sv*hX#*it-u?WEVsz}3^r<xSWY@<d<#!=#dnZWDBmet4U4CUeL%U#`#&xQ>pWdV
zfI#}jk7=R~CaGSi5D4RG<kHd?C0kpU*t}{WZq$6E<BG%7eVq(u)C^o<#N{l#k!QRJ
zWS}rStY_ at mXVvA-O|~m;i|Jah`9q^_J=0zTBTD{hoOe80<|Dm9s~|GFDXvb~o*r;&
z`Y+&QnV*O+9<uDw<Ie%BF^x(n7+rTi_^l;G#mm5d$iI5 at UYMlb76ZdJ^~ZVs{5~r#
zEF_T)7N0wr=nui|4L;;cFcqnJC7xT(FBVyj1t7~K|EapLI*%tjD$CTRQ4`9AVS7ET
z`ezQu#tyvC`dQLTM%02l3`>G?F-??3dq~;^0I{c3h$flrA7oA$;!>Z*z+ij-Oy0DJ
z)Il@#MS<^EkZ0h7)34P=`k0`1=L$z^+*oG$wqXGuuU~NI#`oi`v2kQGt7Mp&fzJSR
zmNi0#q#qS1nsBA<d09L%BK~2Ff<Wq=r143ecqO7NJy+qX)o%@G<4IT?<I*x2ur^Fb
zMw{QAH`*_3%kgN<UeRjIo<r$Xex4=i9TW&-6ns=kdoRD56StMcPZIoAQ207nBW0dQ
zP<mG#A-%CJSJO~jCkQ{%PzRL-Uv)bmTz39gi4yg)*569Z4w!hd*O{7$yk)M_9&*yn
zK<{BJu;oZ4aqhn~6XVTWzj{ZZ5ZzU-W6lK5xq4xBN^FyYg`p2lqo+F%i50OP`)#|M
zTv#aLmU?ZPJh%tSqhDuKe}*6EB<dq_D2NI~B8z*B<)JUy@#S)sc5oSS!KJ}8WmWBW
zrBCI6#QxuJ&a!+{z^HnwIN4{zUR6o-E%_?3g|)B{P}8^b7!dI~qyIjIvYbfKJO)Oy
zFmTAKDv3NeQU1LI_Z?pdb#R(W$U^r$us44#YJ1%#G$0^zU3NV=fn7m8M2l+l7{o$b
zD921svOioc{n*FbQ9YgkD+2(4G!_wj7cW$W^lN|mKl!zYDui^tu%?jAPY8 at Kha&TL
z*U=9J3r<7ysMjCbeJM@*qiL*`ez?`bVJg8+g0K;v;y9<~1}io^o(c&&jzeJ%uT(t{
zC{hDTZgslerweD}$Rq1~10HkUn=Uz-cEx#yuh@`;EG*T_TjF at b%nZ=0dBGA2C at bjb
zSfLE_`!7U}c>Al%<P2McFDi<Zl{Uc1)LwA7dqrJ$zVJJPwWW{_1$q~cJZ#YfEJ*<i
z631Der0ia^xwg%IDP8^I<Q=e?MNqmji(DJwvj$sB&`T3gGP6nP0KyG|DnI8gVf6;;
zH&4=Di*qrX37JtE)9PoExyk=lmnM8#ORk+!leOJ{YSpWZk>O*tfABwlF<rY|fB7`S
z+oZ>{%z-ModNHj~QGe;bo?LvOg{qsV_rf3;v!LQB*7(-^z>Ee}6s*@y at 2#)=d;sT~
zVX<v+CD)@q*#<Ba74TZE;G9~1 at mTM{wb)Pea(0~1aF*vx-Bp`lQk0FEWgON*T)}az
ztMnWWh2^O3^N1#X`Jh7zinp$<hVI#u)j}nK>~AQ{_9)N{m>FPFcN2LH(+eEG>_5B)
zu`w$o>3FKawDP8~3K)W&6gII9P;tVH_yB|;!}Cbyz5HT~1dbLwUb+pVwED{p_*=Q7
zd&vHc7Bh2&w5+Sw!{V#g=&E(;M8^?^2rS$Ef%rzhtbiF8A3$#M<u{7U;Hf`vo$r}1
zXQ}wZMA7&n3ImlX9tXVFk(a2(Y%G2KbYw1fU+<L=mztRPPGaBx=GCH#pSv+(muzS!
zo6%)h(XxApcw8~umr^U7z5C*|zZ0ZuWjRh;+n%V>wWZCBDcyP!*K%iVTvESQy|+^*
z8$-S)A^TO!&X=#*Yi}n~oU9#g%JU-$0jMn1fR^2rt_<Iyj;_GYOXd{H-IFS2F8AGP
r_A8Fpxf`?{egEfN3rTm{6Aq{2g2*D}2Yl4w8#Gm=m#|6&)1dzcvSeKg

literal 0
HcmV?d00001

-- 
2.34.1



From apatel at ventanamicro.com  Sat Jun 10 21:08:55 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun, 11 Jun 2023 09:38:55 +0530
Subject: [PATCH 0/2] OpenSBI logo and copyright update
Message-ID: <20230611040857.51858-1-apatel@ventanamicro.com>

The OpenSBI project does have an official logo which was designed
few months back. This logo is reviewed and approved by RISC-V
international. In fact, some of the RISC-V international slides
already use the official OpenSBI logo.

We add the official logo to the OpenSBI sources so that anyone can:
* Use it in presentations
* Create laptop stickers
* ... and more ...

We also update project copyright information in the top-level
README.md.

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

Anup Patel (2):
  docs: Add OpenSBI logo and use it in the top-level README.md
  README.md: Improve project copyright information

 README.md                               |   8 ++++++--
 docs/riscv_opensbi_logo_final_color.png | Bin 0 -> 7758 bytes
 docs/riscv_opensbi_logo_final_grey.png  | Bin 0 -> 9159 bytes
 3 files changed, 6 insertions(+), 2 deletions(-)
 create mode 100644 docs/riscv_opensbi_logo_final_color.png
 create mode 100644 docs/riscv_opensbi_logo_final_grey.png

-- 
2.34.1



From apatel at ventanamicro.com  Sat Jun 10 21:08:57 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun, 11 Jun 2023 09:38:57 +0530
Subject: [PATCH 2/2] README.md: Improve project copyright information
In-Reply-To: <20230611040857.51858-1-apatel@ventanamicro.com>
References: <20230611040857.51858-1-apatel@ventanamicro.com>
Message-ID: <20230611040857.51858-3-apatel@ventanamicro.com>

Over-time a lot of organizations and individuals have contributed to
the OpenSBI project so let us add copyright RISC-V International to
respect the contributions from all RISC-V members.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 README.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index bb09fdf..73de8ea 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,10 @@ RISC-V Open Source Supervisor Binary Interface (OpenSBI)
 Copyright and License
 ---------------------
 
-The OpenSBI project is copyright (c) 2019 Western Digital Corporation
-or its affiliates and other contributors.
+The OpenSBI project is:
+
+* Copyright (c) 2019 Western Digital Corporation or its affiliates
+* Copyright (c) 2023 RISC-V International
 
 It is distributed under the terms of the BSD 2-clause license
 ("Simplified BSD License" or "FreeBSD License", SPDX: *BSD-2-Clause*).
-- 
2.34.1



From guoren at kernel.org  Sun Jun 11 17:57:36 2023
From: guoren at kernel.org (Guo Ren)
Date: Mon, 12 Jun 2023 08:57:36 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
References: <20230523094649.4100554-1-guoren@kernel.org> <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud> <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy> <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
Message-ID: <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>

Hi Conor,

Jisheng Zhang would update the Linux yaml patch, here is the final dts
format of the reset controller:

               reset-controller at ffff019050 {
                       compatible = "thead,cpu-reset";
                       reg = <0xff 0xff019050 0x0 0x4>, <0xff
0xff015004 0x0 0x0>;
                       reset-ctrl = <0x1c>;
                       clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
0x7c5 0x7cc 0x7ce>;
                };

The reset-ctrl is used to control different parts of soc, generally, a
bit indicates a reset signal (a core/a interconnect/a subsystem).

On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
>
> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
> >
> >
> >
> > On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
> >
> > >So it could be "thead,cpu-reset", okay?
> >
> > As a generic fallback compatible.
> >
> > >Actually, our core could let SoC vendors define their own custom
> > >CSRs/custom reset values of CSRs, so we don't know what would be added
> > >in the future. Put a array in dts instead of hard-code table is much
> > >more flexiblity.
> >
> > If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
> Yes, that is what we want. th1520 is a example.
>
> Thanks for the review and correction! Your help is greatly appreciated
> in improving th1520 upstream.
>
> >
> > Thanks,
> > Conor.
>
>
>
> --
> Best Regards
>  Guo Ren



-- 
Best Regards
 Guo Ren


From jrtc27 at jrtc27.com  Sun Jun 11 18:05:04 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Mon, 12 Jun 2023 02:05:04 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
References: <20230523094649.4100554-1-guoren@kernel.org>
 <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud>
 <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy>
 <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud>
 <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
Message-ID: <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com>

On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
> 
> Hi Conor,
> 
> Jisheng Zhang would update the Linux yaml patch, here is the final dts
> format of the reset controller:
> 
>               reset-controller at ffff019050 {
>                       compatible = "thead,cpu-reset";
>                       reg = <0xff 0xff019050 0x0 0x4>, <0xff
> 0xff015004 0x0 0x0>;
>                       reset-ctrl = <0x1c>;
>                       clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3

This is pretty horrible, there?s no indirect CSR read/write
instruction, so what are you expecting drivers to do with this? Have a
big switch statement for every possible CSR?

Jess

> 0x7c5 0x7cc 0x7ce>;
>                };
> 
> The reset-ctrl is used to control different parts of soc, generally, a
> bit indicates a reset signal (a core/a interconnect/a subsystem).
> 
> On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
>> 
>> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
>>> 
>>> 
>>> 
>>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
>>> 
>>>> So it could be "thead,cpu-reset", okay?
>>> 
>>> As a generic fallback compatible.
>>> 
>>>> Actually, our core could let SoC vendors define their own custom
>>>> CSRs/custom reset values of CSRs, so we don't know what would be added
>>>> in the future. Put a array in dts instead of hard-code table is much
>>>> more flexiblity.
>>> 
>>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
>> Yes, that is what we want. th1520 is a example.
>> 
>> Thanks for the review and correction! Your help is greatly appreciated
>> in improving th1520 upstream.
>> 
>>> 
>>> Thanks,
>>> Conor.
>> 
>> 
>> 
>> --
>> Best Regards
>> Guo Ren
> 
> 
> 
> -- 
> Best Regards
> Guo Ren



From wxjstz at 126.com  Mon Jun 12 01:09:47 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:47 +0800
Subject: [PATCH v6 00/12] Improve sbi_console
Message-ID: <20230612080959.571293-1-wxjstz@126.com>

v5 changes:
- PATCH12: fix printf("%%") missing USED_TBUF;  
- add PATCH14, Fix invalid directive print

v4 changes:
- PATCH11: Simplify printc
- add PATCH13, handle special case

v3 changes:
- PATCH11: Simplify get info->type
- PATCH12: Change the way to keep USED_TBUF by and to reset it by use_tbuf

v2 changes:
- add patch 10-12

Xiang W (12):
  lib: sbi: Fix how print gets flags
  lib: sbi: print not fill '0' when left-aligned
  lib: sbi: Add '+' flags for print
  lib: sbi: Add ' ' '\'' flags for print
  lib: sbi: implifying the parameters of printi
  lib: sbi: print add 'o' type
  lib: sbi: Fix printi
  lib: sbi: Simplify prints
  lib: sbi: sbi_console.c code re-layout
  lib: sbi: Add print_info for sbi_console.c
  lib: sbi: Fix timing of clearing tbuf
  lib: sbi: Fix missing '\0' when buffer szie equal 1

 lib/sbi/sbi_console.c | 413 ++++++++++++++++++++++--------------------
 1 file changed, 212 insertions(+), 201 deletions(-)

-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:50 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:50 +0800
Subject: [PATCH v6 03/12] lib: sbi: Add '+' flags for print
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-4-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index b7d0896..75fd5ac 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -120,6 +120,7 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 #define PAD_RIGHT 1
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
+#define PAD_SIGN 8
 #define PRINT_BUF_LEN 64
 
 #define va_start(v, l) __builtin_va_start((v), l)
@@ -186,15 +187,18 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		  int width, int flags, int letbase)
 {
-	char print_buf[PRINT_BUF_LEN];
-	char *s;
-	int neg = 0, pc = 0;
+	char *s, sign, print_buf[PRINT_BUF_LEN];
+	int pc = 0;
 	u64 t;
 	unsigned long long u = i;
 
-	if (sg && b == 10 && i < 0) {
-		neg = 1;
-		u   = -i;
+	if (sg && b == 10) {
+		if ((flags & PAD_SIGN) && i > 0)
+			sign = '+';
+		if (i < 0) {
+			sign = '-';
+			u = -i;
+		}
 	}
 
 	s  = print_buf + PRINT_BUF_LEN - 1;
@@ -221,13 +225,13 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
 		*--s = '0';
 	}
 
-	if (neg) {
+	if (sign) {
 		if (width && (flags & PAD_ZERO)) {
-			printc(out, out_len, '-');
+			printc(out, out_len, sign);
 			++pc;
 			--width;
 		} else {
-			*--s = '-';
+			*--s = sign;
 		}
 	}
 
@@ -275,6 +279,9 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '-':
 					flags |= PAD_RIGHT;
 					break;
+				case '+':
+					flags |= PAD_SIGN;
+					break;
 				case '#':
 					flags |= PAD_ALTERNATE;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:55 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:55 +0800
Subject: [PATCH v6 08/12] lib: sbi: Simplify prints
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-9-wxjstz@126.com>

When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6f714f0..824ff6e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -151,24 +151,11 @@ static void printc(char **out, u32 *out_len, char ch)
 static int prints(char **out, u32 *out_len, const char *string, int width,
 		  int flags)
 {
-	int pc	     = 0;
-	char padchar = ' ';
-
-	if (width > 0) {
-		int len = 0;
-		const char *ptr;
-		for (ptr = string; *ptr; ++ptr)
-			++len;
-		if (len >= width)
-			width = 0;
-		else
-			width -= len;
-		if (flags & PAD_ZERO)
-			padchar = '0';
-	}
+	int pc = 0;
+	width -= sbi_strlen(string);
 	if (!(flags & PAD_RIGHT)) {
 		for (; width > 0; --width) {
-			printc(out, out_len, padchar);
+			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
 			++pc;
 		}
 	}
@@ -177,7 +164,7 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 		++pc;
 	}
 	for (; width > 0; --width) {
-		printc(out, out_len, padchar);
+		printc(out, out_len, ' ');
 		++pc;
 	}
 
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:49 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:49 +0800
Subject: [PATCH v6 02/12] lib: sbi: print not fill '0' when left-aligned
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-3-wxjstz@126.com>

Left alignment and padding '0' should not exist at the same time,
this patch is not padded with 0 when left aligned.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6e07663..b7d0896 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
+			if (flags & PAD_RIGHT)
+				flags &= ~PAD_ZERO;
 			/* Get width */
 			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:54 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:54 +0800
Subject: [PATCH v6 07/12] lib: sbi: Fix printi
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-8-wxjstz@126.com>

Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 047c51e..6f714f0 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -227,23 +227,33 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ALTERNATE) {
-		if ((b == 16) && (letbase == 'A')) {
-			*--s = 'X';
-		} else if ((b == 16) && (letbase == 'a')) {
-			*--s = 'x';
-		}
-		*--s = '0';
-	}
-
-	if (sign) {
-		if (width && (flags & PAD_ZERO)) {
+	if (flags & PAD_ZERO) {
+		if (sign) {
 			printc(out, out_len, sign);
 			++pc;
 			--width;
-		} else {
-			*--s = sign;
 		}
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16 || b == 8) {
+				printc(out, out_len, '0');
+				++pc;
+				--width;
+			}
+			if (b == 16) {
+				printc(out, out_len, 'x' - 'a' + letbase);
+				++pc;
+				--width;
+			}
+		}
+	} else {
+		if (i && (flags & PAD_ALTERNATE)) {
+			if (b == 16)
+				*--s = 'x' - 'a' + letbase;
+			if (b == 16 || b == 8)
+				*--s = '0';
+		}
+		if (sign)
+			*--s = sign;
 	}
 
 	return pc + prints(out, out_len, s, width, flags);
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:57 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:57 +0800
Subject: [PATCH v6 10/12] lib: sbi: Add print_info for sbi_console.c
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-11-wxjstz@126.com>

Create a structure print_info for print, this structure simplifies
parameter passing.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 235 +++++++++++++++++++++---------------------
 1 file changed, 120 insertions(+), 115 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index af93f51..c227b0f 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -27,11 +27,22 @@
 
 typedef __builtin_va_list va_list;
 
+struct print_info {
+	char *out;
+	int len;
+	int pos;
+	int pc;
+	int flags;
+	int width;
+	int wcnt;
+	char type;
+};
+
 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)
 {
 	if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
@@ -128,70 +139,63 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-static void printc(char **out, u32 *out_len, char ch)
+static void printc(struct print_info *info, char ch)
 {
-	if (!out) {
+	/* output to the console */
+	if (info->out == NULL) {
 		sbi_putc(ch);
+		info->pc++;
 		return;
 	}
 
-	/*
-	 * The *printf entry point functions have enforced that (*out) can
-	 * only be null when out_len is non-null and its value is zero.
-	 */
-	if (!out_len || *out_len > 1) {
-		*(*out)++ = ch;
-		**out = '\0';
-	}
+	/* unknown buffer length */
+	if (info->len == 0)
+		goto append;
 
-	if (out_len && *out_len > 0)
-		--(*out_len);
+	/* The buffer is long enough to add new characters */
+	if (info->len - info->pos > 1)
+		goto append;
+	return;
+
+append:
+	info->out[info->pos++] = ch;
+	info->out[info->pos] = '\0';
+	info->pc++;
 }
 
-static int prints(char **out, u32 *out_len, const char *string, int width,
-		  int flags)
+static void prints(struct print_info *info, const char *string)
 {
-	int pc = 0;
-	width -= sbi_strlen(string);
-	if (!(flags & PAD_RIGHT)) {
-		for (; width > 0; --width) {
-			printc(out, out_len, flags & PAD_ZERO ? '0' : ' ');
-			++pc;
-		}
-	}
-	for (; *string; ++string) {
-		printc(out, out_len, *string);
-		++pc;
-	}
-	for (; width > 0; --width) {
-		printc(out, out_len, ' ');
-		++pc;
+	info->wcnt += sbi_strlen(string);
+	if (!(info->flags & PAD_RIGHT)) {
+		for (; info->wcnt < info->width; info->wcnt++)
+			printc(info, info->flags & PAD_ZERO ? '0' : ' ');
 	}
-
-	return pc;
+	for (; *string; ++string)
+		printc(info, *string);
+	for (; info->wcnt < info->width; info->wcnt++)
+		printc(info, ' ');
 }
 
-static int printi(char **out, u32 *out_len, long long i,
-		  int width, int flags, int type)
+static void printi(struct print_info *info, long long i)
 {
-	int pc = 0;
 	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
 	unsigned long long u, b, t;
 
 	b = 10;
 	letbase = 'a';
-	if (type == 'o')
+	if (info->type == 'o')
 		b = 8;
-	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+	else if (info->type == 'x' || info->type == 'X'
+			 || info->type == 'p' || info->type == 'P') {
 		b = 16;
 		letbase &= ~0x20;
-		letbase |= type & 0x20;
+		letbase |= info->type & 0x20;
 	}
 
 	u = i;
 	sign = 0;
-	if (type == 'i' || type == 'd') {
-		if ((flags & PAD_SIGN) && i > 0)
+	if (info->type == 'i' || info->type == 'd') {
+		if ((info->flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
 			sign = '-';
@@ -214,26 +218,23 @@ static int printi(char **out, u32 *out_len, long long i,
 		}
 	}
 
-	if (flags & PAD_ZERO) {
+	if (info->flags & PAD_ZERO) {
 		if (sign) {
-			printc(out, out_len, sign);
-			++pc;
-			--width;
+			printc(info, sign);
+			++info->wcnt;
 		}
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16 || b == 8) {
-				printc(out, out_len, '0');
-				++pc;
-				--width;
+				printc(info, '0');
+				++info->wcnt;
 			}
 			if (b == 16) {
-				printc(out, out_len, 'x' - 'a' + letbase);
-				++pc;
-				--width;
+				printc(info, 'x' - 'a' + letbase);
+				++info->wcnt;
 			}
 		}
 	} else {
-		if (i && (flags & PAD_ALTERNATE)) {
+		if (i && (info->flags & PAD_ALTERNATE)) {
 			if (b == 16)
 				*--s = 'x' - 'a' + letbase;
 			if (b == 16 || b == 8)
@@ -243,15 +244,16 @@ static int printi(char **out, u32 *out_len, long long i,
 			*--s = sign;
 	}
 
-	return pc + prints(out, out_len, s, width, flags);
+	prints(info, s);
 }
 
-static int print(char **out, u32 *out_len, const char *format, va_list args)
+static void print(struct print_info *info, const char *format, va_list args)
 {
 	bool flags_done;
-	int width, flags, pc = 0;
-	char type, scr[2], *tout;
-	bool use_tbuf = (!out) ? true : false;
+	char scr[2];
+	bool use_tbuf = (!info->out) ? true : false;
+	info->pos = 0;
+	info->pc = 0;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -259,19 +261,15 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 	 * when out == NULL.
 	 */
 	if (use_tbuf) {
-		console_tbuf_len = CONSOLE_TBUF_MAX;
-		tout = console_tbuf;
-		out = &tout;
-		out_len = &console_tbuf_len;
+		info->out = console_tbuf;
+		info->len = CONSOLE_TBUF_MAX;
 	}
 
 	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 (use_tbuf && (info->len - info->pos <= 1)) {
+			nputs_all(info->out, info->pos);
+			info->pos = 0;
+		}		
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -279,21 +277,21 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			flags = 0;
+			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
 				case '-':
-					flags |= PAD_RIGHT;
+					info->flags |= PAD_RIGHT;
 					break;
 				case '+':
-					flags |= PAD_SIGN;
+					info->flags |= PAD_SIGN;
 					break;
 				case '#':
-					flags |= PAD_ALTERNATE;
+					info->flags |= PAD_ALTERNATE;
 					break;
 				case '0':
-					flags |= PAD_ZERO;
+					info->flags |= PAD_ZERO;
 					break;
 				case ' ':
 				case '\'':
@@ -306,153 +304,160 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				if (!flags_done)
 					++format;
 			}
-			if (flags & PAD_RIGHT)
-				flags &= ~PAD_ZERO;
+			if (info->flags & PAD_RIGHT)
+				info->flags &= ~PAD_ZERO;
 			/* Get width */
-			width = 0;
+			info->width = 0;
+			info->wcnt = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
-				width *= 10;
-				width += *format - '0';
+				info->width *= 10;
+				info->width += *format - '0';
 			}
+			info->type = *format;
 			if (*format == 's') {
 				char *s = va_arg(args, char *);
-				pc += prints(out, out_len, s ? s : "(null)",
-					     width, flags);
+				prints(info, s ? s : "(null)");
 				continue;
 			}
 			if ((*format == 'd') || (*format == 'i')) {
-				pc += printi(out, out_len, va_arg(args, int),
-					     width, flags, *format);
+				printi(info, va_arg(args, int));
 				continue;
 			}
 			if ((*format == 'u') || (*format == 'o')
 					 || (*format == 'x') || (*format == 'X')) {
-				pc += printi(out, out_len, va_arg(args, unsigned int),
-					     width, flags, *format);
+				printi(info, va_arg(args, unsigned int));
 				continue;
 			}
 			if ((*format == 'p') || (*format == 'P')) {
-				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
-					     width, flags, *format);
+				printi(info, (uintptr_t)va_arg(args, void*));
 				continue;
 			}
 			if (*format == 'l') {
-				type = 'i';
+				info->type = 'i';
 				if (format[1] == 'l') {
 					++format;
 					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
-						type = *format;
+						info->type = *format;
 					}
-					pc += printi(out, out_len, va_arg(args, long long),
-						width, flags, type);
+					printi(info, va_arg(args, long long));
 					continue;
 				}
 				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-					type = *format;
+					info->type = *format;
 				}
-				if ((type == 'd') || (type == 'i'))
-					pc += printi(out, out_len, va_arg(args, long),
-					     width, flags, type);
+				if ((info->type == 'd') || (info->type == 'i'))
+					printi(info, va_arg(args, long));
 				else
-					pc += printi(out, out_len, va_arg(args, unsigned long),
-					     width, flags, type);
+					printi(info, va_arg(args, unsigned long));
 				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
 				scr[0] = va_arg(args, int);
 				scr[1] = '\0';
-				pc += prints(out, out_len, scr, width, flags);
+				prints(info, scr);
 				continue;
 			}
 		} else {
 literal:
-			printc(out, out_len, *format);
-			++pc;
+			printc(info, *format);
 		}
 	}
 
-	if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
-		nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
-
-	return pc;
+	if (use_tbuf && info->pos > 0)
+		nputs_all(info->out, info->pos);
 }
 
 int sbi_sprintf(char *out, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = 0;
+
 
 	if (unlikely(!out))
 		sbi_panic("sbi_sprintf called with NULL output string\n");
 
 	va_start(args, format);
-	retval = print(&out, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = out;
+	info.len = out_sz;
+
 
 	if (unlikely(!out && out_sz != 0))
 		sbi_panic("sbi_snprintf called with NULL output string and "
 			  "output size is not zero\n");
 
 	va_start(args, format);
-	retval = print(&out, &out_sz, format, args);
+	print(&info, format, args);
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_printf(const char *format, ...)
 {
 	va_list args;
-	int retval;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	retval = print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-	return retval;
+	return info.pc;
 }
 
 int sbi_dprintf(const char *format, ...)
 {
 	va_list args;
-	int retval = 0;
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
+
 
 	va_start(args, format);
 	if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) {
 		spin_lock(&console_out_lock);
-		retval = print(NULL, NULL, format, args);
+		print(&info, format, args);
 		spin_unlock(&console_out_lock);
 	}
 	va_end(args);
 
-	return retval;
+	return info.pc;
 }
 
 void sbi_panic(const char *format, ...)
 {
 	va_list args;
+	struct print_info info;
+	info.out = NULL;
+	info.len = 0;
 
 	spin_lock(&console_out_lock);
 	va_start(args, format);
-	print(NULL, NULL, format, args);
+	print(&info, format, args);
 	va_end(args);
 	spin_unlock(&console_out_lock);
 
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:53 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:53 +0800
Subject: [PATCH v6 06/12] lib: sbi: print add 'o' type
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-7-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index a9a2ed6..047c51e 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -328,7 +328,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 					     width, flags, *format);
 				continue;
 			}
-			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+			if ((*format == 'u') || (*format == 'o')
+					 || (*format == 'x') || (*format == 'X')) {
 				pc += printi(out, out_len, va_arg(args, unsigned int),
 					     width, flags, *format);
 				continue;
@@ -342,7 +343,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				type = 'i';
 				if (format[1] == 'l') {
 					++format;
-					if ((format[1] == 'u')
+					if ((format[1] == 'u') || (format[1] == 'o')
 							|| (format[1] == 'd') || (format[1] == 'i')
 							|| (format[1] == 'x') || (format[1] == 'X')) {
 						++format;
@@ -352,7 +353,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 						width, flags, type);
 					continue;
 				}
-				if ((format[1] == 'u')
+				if ((format[1] == 'u') || (format[1] == 'o')
 						|| (format[1] == 'd') || (format[1] == 'i')
 						|| (format[1] == 'x') || (format[1] == 'X')) {
 					++format;
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:48 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:48 +0800
Subject: [PATCH v6 01/12] lib: sbi: Fix how print gets flags
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-2-wxjstz@126.com>

The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd..6e07663 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -236,6 +236,7 @@ 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)
 {
+	bool flags_done;
 	int width, flags, pc = 0;
 	char scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
@@ -262,25 +263,33 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 
 		if (*format == '%') {
 			++format;
-			width = flags = 0;
 			if (*format == '\0')
 				break;
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			if (*format == '-') {
-				++format;
-				flags = PAD_RIGHT;
-			}
-			if (*format == '#') {
-				++format;
-				flags |= PAD_ALTERNATE;
-			}
-			while (*format == '0') {
-				++format;
-				flags |= PAD_ZERO;
+			flags = 0;
+			flags_done = false;
+			while (!flags_done) {
+				switch (*format) {
+				case '-':
+					flags |= PAD_RIGHT;
+					break;
+				case '#':
+					flags |= PAD_ALTERNATE;
+					break;
+				case '0':
+					flags |= PAD_ZERO;
+					break;
+				default:
+					flags_done = true;
+					break;
+				}
+				if (!flags_done)
+					++format;
 			}
 			/* Get width */
+			width = 0;
 			for (; *format >= '0' && *format <= '9'; ++format) {
 				width *= 10;
 				width += *format - '0';
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:11:02 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:11:02 +0800
Subject: [PATCH v6 11/12] lib: sbi: Fix timing of clearing tbuf
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612081102.571456-1-wxjstz@126.com>

A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index c227b0f..2eefee1 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -18,6 +18,8 @@
 #define PAD_ZERO 2
 #define PAD_ALTERNATE 4
 #define PAD_SIGN 8
+#define USED_TBUF (1 << (8 * sizeof(int) - 1))
+
 #define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
@@ -161,6 +163,11 @@ append:
 	info->out[info->pos++] = ch;
 	info->out[info->pos] = '\0';
 	info->pc++;
+
+	if ((info->flags & USED_TBUF) && (info->len - info->pos <= 1)) {
+		nputs_all(info->out, info->pos);
+		info->pos = 0;
+	}
 }
 
 static void prints(struct print_info *info, const char *string)
@@ -266,10 +273,9 @@ static void print(struct print_info *info, const char *format, va_list args)
 	}
 
 	for (; *format != 0; ++format) {
-		if (use_tbuf && (info->len - info->pos <= 1)) {
-			nputs_all(info->out, info->pos);
-			info->pos = 0;
-		}		
+		info->flags = 0;
+		if (use_tbuf)
+			info->flags |= USED_TBUF;
 		if (*format == '%') {
 			++format;
 			if (*format == '\0')
@@ -277,7 +283,6 @@ static void print(struct print_info *info, const char *format, va_list args)
 			if (*format == '%')
 				goto literal;
 			/* Get flags */
-			info->flags = 0;
 			flags_done = false;
 			while (!flags_done) {
 				switch (*format) {
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:52 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:52 +0800
Subject: [PATCH v6 05/12] lib: sbi: implifying the parameters of printi
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-6-wxjstz@126.com>

The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 127 +++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 77 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 6780ff2..a9a2ed6 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -184,15 +184,26 @@ static int prints(char **out, u32 *out_len, const char *string, int width,
 	return pc;
 }
 
-static int printi(char **out, u32 *out_len, long long i, int b, int sg,
-		  int width, int flags, int letbase)
+static int printi(char **out, u32 *out_len, long long i,
+		  int width, int flags, int type)
 {
-	char *s, sign, print_buf[PRINT_BUF_LEN];
 	int pc = 0;
-	u64 t;
-	unsigned long long u = i;
+	char *s, sign, letbase, print_buf[PRINT_BUF_LEN];
+	unsigned long long u, b, t;
+
+	b = 10;
+	letbase = 'a';
+	if (type == 'o')
+		b = 8;
+	else if (type == 'x' || type == 'X' || type == 'p' || type == 'P') {
+		b = 16;
+		letbase &= ~0x20;
+		letbase |= type & 0x20;
+	}
 
-	if (sg && b == 10) {
+	u = i;
+	sign = 0;
+	if (type == 'i' || type == 'd') {
 		if ((flags & PAD_SIGN) && i > 0)
 			sign = '+';
 		if (i < 0) {
@@ -242,9 +253,8 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 {
 	bool flags_done;
 	int width, flags, pc = 0;
-	char scr[2], *tout;
+	char type, scr[2], *tout;
 	bool use_tbuf = (!out) ? true : false;
-	unsigned long long tmp;
 
 	/*
 	 * The console_tbuf is protected by console_out_lock and
@@ -315,83 +325,46 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 			}
 			if ((*format == 'd') || (*format == 'i')) {
 				pc += printi(out, out_len, va_arg(args, int),
-					     10, 1, width, flags, '0');
-				continue;
-			}
-			if (*format == 'x') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'a');
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'X') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 16, 0,
-					     width, flags, 'A');
+			if ((*format == 'u') || (*format == 'x') || (*format == 'X')) {
+				pc += printi(out, out_len, va_arg(args, unsigned int),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'u') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned int), 10, 0,
-					     width, flags, 'a');
+			if ((*format == 'p') || (*format == 'P')) {
+				pc += printi(out, out_len, (uintptr_t)va_arg(args, void*),
+					     width, flags, *format);
 				continue;
 			}
-			if (*format == 'p') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'a');
-				continue;
-			}
-			if (*format == 'P') {
-				pc += printi(out, out_len,
-					     va_arg(args, unsigned long), 16, 0,
-					     width, flags, 'A');
-				continue;
-			}
-			if (*format == 'l' && *(format + 1) == 'l') {
-				tmp = va_arg(args, unsigned long long);
-				if (*(format + 2) == 'u') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 10, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'x') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'a');
-				} else if (*(format + 2) == 'X') {
-					format += 2;
-					pc += printi(out, out_len, tmp, 16, 0,
-						     width, flags, 'A');
-				} else {
-					format += 1;
-					pc += printi(out, out_len, tmp, 10, 1,
-						     width, flags, '0');
+			if (*format == 'l') {
+				type = 'i';
+				if (format[1] == 'l') {
+					++format;
+					if ((format[1] == 'u')
+							|| (format[1] == 'd') || (format[1] == 'i')
+							|| (format[1] == 'x') || (format[1] == 'X')) {
+						++format;
+						type = *format;
+					}
+					pc += printi(out, out_len, va_arg(args, long long),
+						width, flags, type);
+					continue;
 				}
-				continue;
-			} else if (*format == 'l') {
-				if (*(format + 1) == 'u') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 10,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'x') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'a');
-				} else if (*(format + 1) == 'X') {
-					format += 1;
-					pc += printi(
-						out, out_len,
-						va_arg(args, unsigned long), 16,
-						0, width, flags, 'A');
-				} else {
-					pc += printi(out, out_len,
-						     va_arg(args, long), 10, 1,
-						     width, flags, '0');
+				if ((format[1] == 'u')
+						|| (format[1] == 'd') || (format[1] == 'i')
+						|| (format[1] == 'x') || (format[1] == 'X')) {
+					++format;
+					type = *format;
 				}
+				if ((type == 'd') || (type == 'i'))
+					pc += printi(out, out_len, va_arg(args, long),
+					     width, flags, type);
+				else
+					pc += printi(out, out_len, va_arg(args, unsigned long),
+					     width, flags, type);
+				continue;
 			}
 			if (*format == 'c') {
 				/* char are converted to int then pushed on the stack */
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:11:21 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:11:21 +0800
Subject: [PATCH v6 12/12] lib: sbi: Fix missing '\0' when buffer szie equal 1
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612081121.571590-1-wxjstz@126.com>

Fix special case: sbi_snprintf(out, 1, ...), The previous code will
not fill the buffer with any char.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 2eefee1..f7fd761 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -157,6 +157,14 @@ static void printc(struct print_info *info, char ch)
 	/* The buffer is long enough to add new characters */
 	if (info->len - info->pos > 1)
 		goto append;
+
+	/*
+	 * special case: sbi_snprintf(out, 1, ...);
+	 * This case never jumps to append, so add '\0' here
+	 */
+	if (info->pos == 0)
+		info->out[0] = '\0';
+
 	return;
 
 append:
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:51 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:51 +0800
Subject: [PATCH v6 04/12] lib: sbi: Add ' ' '\'' flags for print
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-5-wxjstz@126.com>

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 75fd5ac..6780ff2 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -288,6 +288,10 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
 				case '0':
 					flags |= PAD_ZERO;
 					break;
+				case ' ':
+				case '\'':
+					/* Ignored flags, do nothing */
+					break;
 				default:
 					flags_done = true;
 					break;
-- 
2.39.2



From wxjstz at 126.com  Mon Jun 12 01:09:56 2023
From: wxjstz at 126.com (Xiang W)
Date: Mon, 12 Jun 2023 16:09:56 +0800
Subject: [PATCH v6 09/12] lib: sbi: sbi_console.c code re-layout
In-Reply-To: <20230612080959.571293-1-wxjstz@126.com>
References: <20230612080959.571293-1-wxjstz@126.com>
Message-ID: <20230612080959.571293-10-wxjstz@126.com>

Move the type definitions and macros in sbi_console.c to the begin
of the file.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_console.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 824ff6e..af93f51 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -14,8 +14,19 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+#define PAD_ALTERNATE 4
+#define PAD_SIGN 8
+#define PRINT_BUF_LEN 64
 #define CONSOLE_TBUF_MAX 256
 
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_end __builtin_va_end
+#define va_arg __builtin_va_arg
+
+typedef __builtin_va_list va_list;
+
 static const struct sbi_console_device *console_dev = NULL;
 static char console_tbuf[CONSOLE_TBUF_MAX];
 static u32 console_tbuf_len;
@@ -117,17 +128,6 @@ unsigned long sbi_ngets(char *str, unsigned long len)
 	return i;
 }
 
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-#define PAD_ALTERNATE 4
-#define PAD_SIGN 8
-#define PRINT_BUF_LEN 64
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_end __builtin_va_end
-#define va_arg __builtin_va_arg
-typedef __builtin_va_list va_list;
-
 static void printc(char **out, u32 *out_len, char ch)
 {
 	if (!out) {
-- 
2.39.2



From ajones at ventanamicro.com  Mon Jun 12 02:13:24 2023
From: ajones at ventanamicro.com (Andrew Jones)
Date: Mon, 12 Jun 2023 11:13:24 +0200
Subject: [PATCH 0/2] OpenSBI logo and copyright update
In-Reply-To: <20230611040857.51858-1-apatel@ventanamicro.com>
References: <20230611040857.51858-1-apatel@ventanamicro.com>
Message-ID: <20230612-3f46ae2a208e71a771eb3281@orel>

On Sun, Jun 11, 2023 at 09:38:55AM +0530, Anup Patel wrote:
> The OpenSBI project does have an official logo which was designed
> few months back. This logo is reviewed and approved by RISC-V
> international. In fact, some of the RISC-V international slides
> already use the official OpenSBI logo.
> 
> We add the official logo to the OpenSBI sources so that anyone can:
> * Use it in presentations
> * Create laptop stickers
> * ... and more ...
> 
> We also update project copyright information in the top-level
> README.md.
> 
> These patches can also be found in logo_v1 branch at:
> https://github.com/avpatel/opensbi.git
> 
> Anup Patel (2):
>   docs: Add OpenSBI logo and use it in the top-level README.md
>   README.md: Improve project copyright information
> 
>  README.md                               |   8 ++++++--
>  docs/riscv_opensbi_logo_final_color.png | Bin 0 -> 7758 bytes
>  docs/riscv_opensbi_logo_final_grey.png  | Bin 0 -> 9159 bytes
>  3 files changed, 6 insertions(+), 2 deletions(-)
>  create mode 100644 docs/riscv_opensbi_logo_final_color.png
>  create mode 100644 docs/riscv_opensbi_logo_final_grey.png
> 
> -- 
> 2.34.1
>

For the series,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From guoren at kernel.org  Mon Jun 12 19:21:09 2023
From: guoren at kernel.org (Guo Ren)
Date: Tue, 13 Jun 2023 10:21:09 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com>
References: <20230523094649.4100554-1-guoren@kernel.org> <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud> <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy> <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com> <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com>
Message-ID: <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>

On Mon, Jun 12, 2023 at 9:05?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>
> On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
> >
> > Hi Conor,
> >
> > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > format of the reset controller:
> >
> >               reset-controller at ffff019050 {
> >                       compatible = "thead,cpu-reset";
> >                       reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > 0xff015004 0x0 0x0>;
> >                       reset-ctrl = <0x1c>;
> >                       clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
>
> This is pretty horrible, there?s no indirect CSR read/write
> instruction, so what are you expecting drivers to do with this? Have a
We've done it in the opensbi:
https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c

A lot of SoC customers would intergrate their own CSRs though our rtl
code interface, these CSRs are initilized in their primary hart in
early boot stage / jtag gdbinit script, the secondary harts just copy
the CSRs' values from boot hart. That means we could provide a unified
way to all customer.

> big switch statement for every possible CSR?
We needn't big switch statement, boot hart store the csrs setting
codes in the memory, and secondary harts excute them to set the csrs.
Here is the code snippet:

struct custom_csr custom_csr[MAX_CUSTOM_CSR];

#define CSR_OPCODE 0x39073
static void clone_csrs(int cnt)
{
unsigned long i;

for (i = 0; i < cnt; i++) {
/* Write csr BIT[31 - 20] to stub */
__reset_thead_csr_stub[3*i + 1] = CSR_OPCODE | (custom_csr[i].index << 20);

/* Mask csr BIT[31 - 20] */
*(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
smp_mb();

/* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
*(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
smp_mb();

RISCV_FENCE_I;

custom_csr[i].value = __fdt_reset_thead_csrr();
}

}
==========

/* Prepare clone csrs */
val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
if (len > 0 && val_w) {
int cnt;

cnt = len / sizeof(fdt32_t);
if (cnt > MAX_CUSTOM_CSR)
sbi_hart_hang();

for (i = 0; i < cnt; i++) {
custom_csr[i].index = fdt32_to_cpu(val_w[i]);
}

if (cnt)
clone_csrs(cnt); // prepare the secondary harts' excution code
}






>
> Jess
>
> > 0x7c5 0x7cc 0x7ce>;
> >                };
> >
> > The reset-ctrl is used to control different parts of soc, generally, a
> > bit indicates a reset signal (a core/a interconnect/a subsystem).
> >
> > On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
> >>
> >> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
> >>>
> >>>
> >>>
> >>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
> >>>
> >>>> So it could be "thead,cpu-reset", okay?
> >>>
> >>> As a generic fallback compatible.
> >>>
> >>>> Actually, our core could let SoC vendors define their own custom
> >>>> CSRs/custom reset values of CSRs, so we don't know what would be added
> >>>> in the future. Put a array in dts instead of hard-code table is much
> >>>> more flexiblity.
> >>>
> >>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
> >> Yes, that is what we want. th1520 is a example.
> >>
> >> Thanks for the review and correction! Your help is greatly appreciated
> >> in improving th1520 upstream.
> >>
> >>>
> >>> Thanks,
> >>> Conor.
> >>
> >>
> >>
> >> --
> >> Best Regards
> >> Guo Ren
> >
> >
> >
> > --
> > Best Regards
> > Guo Ren
>


-- 
Best Regards
 Guo Ren


From guoren at kernel.org  Mon Jun 12 19:31:40 2023
From: guoren at kernel.org (Guo Ren)
Date: Tue, 13 Jun 2023 10:31:40 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <20230612-graveness-uncloak-5f3634a45339@spud>
References: <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy> <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com> <20230612-graveness-uncloak-5f3634a45339@spud>
Message-ID: <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>

On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
>
> On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > Hi Conor,
> >
> > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > format of the reset controller:
> >
> >                reset-controller at ffff019050 {
> >                        compatible = "thead,cpu-reset";
> >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > 0xff015004 0x0 0x0>;
> >                        reset-ctrl = <0x1c>;
> >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > 0x7c5 0x7cc 0x7ce>;
> >                 };
> >
> > The reset-ctrl is used to control different parts of soc, generally, a
> > bit indicates a reset signal (a core/a interconnect/a subsystem).
>
> So what is "reset-ctrl"? Values to write into a register? A register
> address?
It's a values, and every bit indicate a reset signal.

> Should this stuff be represented as a proper reset controller, with a
> "resets" property in each of the controlled nodes w/ a phandle + index?
> It's hard to say with your explanation here :/ Is there some
> documentation in English that I could look at? Unfortunately that's only
> language I speak that anyone writes technical docs in.
Sorry, there is no exact document about reset-ctrl, becasue every SoC
customers has some little difference here.

For SoC intergration, every t-head CPU would give a reset signal, and
SoC customer could intergrate them into their own reset control
register, generally, every bit indicate a reset signal. Some of them
would combine it with their SoC bus reset signal, so we provide a
flexiable/undefined setting value here.

This has been implemented in opensbi, and we have used it many years :)
https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c

val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
if (len > 0 && val) {
p = (void *)(ulong)fdt64_to_cpu(*val);

val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
if (len > 0 && val_w) {
tmp = fdt32_to_cpu(*val_w);
tmp |= readl(p);
writel(tmp, p);
}
}


>
> Thanks,
> Conor.



-- 
Best Regards
 Guo Ren


From jrtc27 at jrtc27.com  Mon Jun 12 19:43:42 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Tue, 13 Jun 2023 03:43:42 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>
References: <20230523094649.4100554-1-guoren@kernel.org>
 <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud>
 <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy>
 <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud>
 <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com>
 <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>
Message-ID: <F519491B-325E-4B8D-961C-FC8965895BA3@jrtc27.com>

On 13 Jun 2023, at 03:21, Guo Ren <guoren at kernel.org> wrote:
> 
> On Mon, Jun 12, 2023 at 9:05?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>> 
>> On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
>>> 
>>> Hi Conor,
>>> 
>>> Jisheng Zhang would update the Linux yaml patch, here is the final dts
>>> format of the reset controller:
>>> 
>>>              reset-controller at ffff019050 {
>>>                      compatible = "thead,cpu-reset";
>>>                      reg = <0xff 0xff019050 0x0 0x4>, <0xff
>>> 0xff015004 0x0 0x0>;
>>>                      reset-ctrl = <0x1c>;
>>>                      clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
>> 
>> This is pretty horrible, there?s no indirect CSR read/write
>> instruction, so what are you expecting drivers to do with this? Have a
> We've done it in the opensbi:
> https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> 
> A lot of SoC customers would intergrate their own CSRs though our rtl
> code interface, these CSRs are initilized in their primary hart in
> early boot stage / jtag gdbinit script, the secondary harts just copy
> the CSRs' values from boot hart. That means we could provide a unified
> way to all customer.
> 
>> big switch statement for every possible CSR?
> We needn't big switch statement, boot hart store the csrs setting
> codes in the memory, and secondary harts excute them to set the csrs.
> Here is the code snippet:
> 
> struct custom_csr custom_csr[MAX_CUSTOM_CSR];
> 
> #define CSR_OPCODE 0x39073
> static void clone_csrs(int cnt)
> {
> unsigned long i;
> 
> for (i = 0; i < cnt; i++) {
> /* Write csr BIT[31 - 20] to stub */
> __reset_thead_csr_stub[3*i + 1] = CSR_OPCODE | (custom_csr[i].index << 20);
> 
> /* Mask csr BIT[31 - 20] */
> *(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
> smp_mb();
> 
> /* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
> *(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
> smp_mb();
> 
> RISCV_FENCE_I;
> 
> custom_csr[i].value = __fdt_reset_thead_csrr();
> }

So you want your highly-privileged firmware to be dynamically
generating code, with the ability to have a WX mapping in the
first place?

Jess

> }
> ==========
> 
> /* Prepare clone csrs */
> val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
> if (len > 0 && val_w) {
> int cnt;
> 
> cnt = len / sizeof(fdt32_t);
> if (cnt > MAX_CUSTOM_CSR)
> sbi_hart_hang();
> 
> for (i = 0; i < cnt; i++) {
> custom_csr[i].index = fdt32_to_cpu(val_w[i]);
> }
> 
> if (cnt)
> clone_csrs(cnt); // prepare the secondary harts' excution code
> }
> 
> 
> 
> 
> 
> 
>> 
>> Jess
>> 
>>> 0x7c5 0x7cc 0x7ce>;
>>>               };
>>> 
>>> The reset-ctrl is used to control different parts of soc, generally, a
>>> bit indicates a reset signal (a core/a interconnect/a subsystem).
>>> 
>>> On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
>>>> 
>>>> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
>>>>> 
>>>>>> So it could be "thead,cpu-reset", okay?
>>>>> 
>>>>> As a generic fallback compatible.
>>>>> 
>>>>>> Actually, our core could let SoC vendors define their own custom
>>>>>> CSRs/custom reset values of CSRs, so we don't know what would be added
>>>>>> in the future. Put a array in dts instead of hard-code table is much
>>>>>> more flexiblity.
>>>>> 
>>>>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
>>>> Yes, that is what we want. th1520 is a example.
>>>> 
>>>> Thanks for the review and correction! Your help is greatly appreciated
>>>> in improving th1520 upstream.
>>>> 
>>>>> 
>>>>> Thanks,
>>>>> Conor.
>>>> 
>>>> 
>>>> 
>>>> --
>>>> Best Regards
>>>> Guo Ren
>>> 
>>> 
>>> 
>>> --
>>> Best Regards
>>> Guo Ren
>> 
> 
> 
> -- 
> Best Regards
> Guo Ren




From conor at kernel.org  Mon Jun 12 08:39:35 2023
From: conor at kernel.org (Conor Dooley)
Date: Mon, 12 Jun 2023 16:39:35 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
References: <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy>
 <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud>
 <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
Message-ID: <20230612-graveness-uncloak-5f3634a45339@spud>

On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> Hi Conor,
> 
> Jisheng Zhang would update the Linux yaml patch, here is the final dts
> format of the reset controller:
> 
>                reset-controller at ffff019050 {
>                        compatible = "thead,cpu-reset";
>                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> 0xff015004 0x0 0x0>;
>                        reset-ctrl = <0x1c>;
>                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> 0x7c5 0x7cc 0x7ce>;
>                 };
> 
> The reset-ctrl is used to control different parts of soc, generally, a
> bit indicates a reset signal (a core/a interconnect/a subsystem).

So what is "reset-ctrl"? Values to write into a register? A register
address?
Should this stuff be represented as a proper reset controller, with a
"resets" property in each of the controlled nodes w/ a phandle + index?
It's hard to say with your explanation here :/ Is there some
documentation in English that I could look at? Unfortunately that's only
language I speak that anyone writes technical docs in.

Thanks,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/opensbi/attachments/20230612/7b279039/attachment-0001.sig>

From guoren at kernel.org  Tue Jun 13 18:07:22 2023
From: guoren at kernel.org (Guo Ren)
Date: Wed, 14 Jun 2023 09:07:22 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <F519491B-325E-4B8D-961C-FC8965895BA3@jrtc27.com>
References: <20230523094649.4100554-1-guoren@kernel.org> <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud> <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy> <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com> <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>
 <F519491B-325E-4B8D-961C-FC8965895BA3@jrtc27.com>
Message-ID: <CAJF2gTRFbh5vV0ktD43z_Nhj04e=FKWtdnO+9jyYyjwQO4tbiw@mail.gmail.com>

On Tue, Jun 13, 2023 at 10:43?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>
> On 13 Jun 2023, at 03:21, Guo Ren <guoren at kernel.org> wrote:
> >
> > On Mon, Jun 12, 2023 at 9:05?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
> >>
> >> On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
> >>>
> >>> Hi Conor,
> >>>
> >>> Jisheng Zhang would update the Linux yaml patch, here is the final dts
> >>> format of the reset controller:
> >>>
> >>>              reset-controller at ffff019050 {
> >>>                      compatible = "thead,cpu-reset";
> >>>                      reg = <0xff 0xff019050 0x0 0x4>, <0xff
> >>> 0xff015004 0x0 0x0>;
> >>>                      reset-ctrl = <0x1c>;
> >>>                      clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> >>
> >> This is pretty horrible, there?s no indirect CSR read/write
> >> instruction, so what are you expecting drivers to do with this? Have a
> > We've done it in the opensbi:
> > https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> >
> > A lot of SoC customers would intergrate their own CSRs though our rtl
> > code interface, these CSRs are initilized in their primary hart in
> > early boot stage / jtag gdbinit script, the secondary harts just copy
> > the CSRs' values from boot hart. That means we could provide a unified
> > way to all customer.
> >
> >> big switch statement for every possible CSR?
> > We needn't big switch statement, boot hart store the csrs setting
> > codes in the memory, and secondary harts excute them to set the csrs.
> > Here is the code snippet:
> >
> > struct custom_csr custom_csr[MAX_CUSTOM_CSR];
> >
> > #define CSR_OPCODE 0x39073
> > static void clone_csrs(int cnt)
> > {
> > unsigned long i;
> >
> > for (i = 0; i < cnt; i++) {
> > /* Write csr BIT[31 - 20] to stub */
> > __reset_thead_csr_stub[3*i + 1] = CSR_OPCODE | (custom_csr[i].index << 20);
> >
> > /* Mask csr BIT[31 - 20] */
> > *(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
> > smp_mb();
> >
> > /* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
> > *(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
> > smp_mb();
> >
> > RISCV_FENCE_I;
> >
> > custom_csr[i].value = __fdt_reset_thead_csrr();
> > }
>
> So you want your highly-privileged firmware to be dynamically
> generating code, with the ability to have a WX mapping in the
> first place?
We don't expect WX mapping, but the current fdt_reset_init is after
the pmp config. I need to move it into early_init. Thx for pointing it
out.



>
> Jess
>
> > }
> > ==========
> >
> > /* Prepare clone csrs */
> > val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
> > if (len > 0 && val_w) {
> > int cnt;
> >
> > cnt = len / sizeof(fdt32_t);
> > if (cnt > MAX_CUSTOM_CSR)
> > sbi_hart_hang();
> >
> > for (i = 0; i < cnt; i++) {
> > custom_csr[i].index = fdt32_to_cpu(val_w[i]);
> > }
> >
> > if (cnt)
> > clone_csrs(cnt); // prepare the secondary harts' excution code
> > }
> >
> >
> >
> >
> >
> >
> >>
> >> Jess
> >>
> >>> 0x7c5 0x7cc 0x7ce>;
> >>>               };
> >>>
> >>> The reset-ctrl is used to control different parts of soc, generally, a
> >>> bit indicates a reset signal (a core/a interconnect/a subsystem).
> >>>
> >>> On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
> >>>>
> >>>> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
> >>>>>
> >>>>>> So it could be "thead,cpu-reset", okay?
> >>>>>
> >>>>> As a generic fallback compatible.
> >>>>>
> >>>>>> Actually, our core could let SoC vendors define their own custom
> >>>>>> CSRs/custom reset values of CSRs, so we don't know what would be added
> >>>>>> in the future. Put a array in dts instead of hard-code table is much
> >>>>>> more flexiblity.
> >>>>>
> >>>>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
> >>>> Yes, that is what we want. th1520 is a example.
> >>>>
> >>>> Thanks for the review and correction! Your help is greatly appreciated
> >>>> in improving th1520 upstream.
> >>>>
> >>>>>
> >>>>> Thanks,
> >>>>> Conor.
> >>>>
> >>>>
> >>>>
> >>>> --
> >>>> Best Regards
> >>>> Guo Ren
> >>>
> >>>
> >>>
> >>> --
> >>> Best Regards
> >>> Guo Ren
> >>
> >
> >
> > --
> > Best Regards
> > Guo Ren
>
>


--
Best Regards
 Guo Ren


From guoren at kernel.org  Tue Jun 13 18:11:01 2023
From: guoren at kernel.org (Guo Ren)
Date: Wed, 14 Jun 2023 09:11:01 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <20230613-define-constrict-7608d966e0e8@spud>
References: <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud> <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud>
Message-ID: <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>

On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
>
> Hey Guo Ren,
>
> On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > format of the reset controller:
> > > >
> > > >                reset-controller at ffff019050 {
> > > >                        compatible = "thead,cpu-reset";
>
> Also, please just add the soc-specific compatibles even if the driver
> will bind against the most common form of it.
>
> > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > 0xff015004 0x0 0x0>;
> > > >                        reset-ctrl = <0x1c>;
> > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > 0x7c5 0x7cc 0x7ce>;
>
> To be honest, I don't actually understand why "clone-csrs" is even part
> of this "cpu-reset" node. It seems to serve a different purpose to
> something that could take various parts of the SoC out of reset.
> IMO, the "clone-csrs" stuff is something that should be done based on
> the soc-level compatible, and not related to the "cpu-reset" node at
> all, which (given the below) sounds more and more like a regular reset
> controller.
We need to put clone-csrs' execution entry into the reset entry (the
first reg address).

        /* Custom reset method for secondary harts */
        val = fdt_getprop(fdt, nodeoff, "entry-reg", &len);
        if (len > 0 && val) {
          p = (char *)(ulong)fdt64_to_cpu(*val);

                val_w = fdt_getprop(fdt, nodeoff, "entry-cnt", &len);
                if (len > 0 && val_w) {
                        tmp = fdt32_to_cpu(*val_w);

                        for (i = 0; i < tmp; i++) {
                                t = (ulong)&__thead_pre_start_warm;
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                writel(t, p + (8 * i));
                                t = (u64)(ulong)&__thead_pre_start_warm >> 32;
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                writel(t, p + (8 * i) + 4);
                                ^^^^^^^^^^^^^^^^^^^^^
                        }
                }

                val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
                if (len > 0 && val) {
                        p = (void *)(ulong)fdt64_to_cpu(*val);

                        val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
                        if (len > 0 && val_w) {
                                tmp = fdt32_to_cpu(*val_w);
                                tmp |= readl(p);
                                writel(tmp, p);
                        }
                }
        }

I don't think we need to separate it, which made maintenance more complex.

>
>
> > > > The reset-ctrl is used to control different parts of soc, generally, a
> > > > bit indicates a reset signal (a core/a interconnect/a subsystem).
> > >
> > > So what is "reset-ctrl"? Values to write into a register? A register
> > > address?
> >
> > It's a values, and every bit indicate a reset signal.
> >
> > > Should this stuff be represented as a proper reset controller, with a
> > > "resets" property in each of the controlled nodes w/ a phandle + index?
> > > It's hard to say with your explanation here :/ Is there some
> > > documentation in English that I could look at? Unfortunately that's only
> > > language I speak that anyone writes technical docs in.
> > Sorry, there is no exact document about reset-ctrl, becasue every SoC
> > customers has some little difference here.
> >
> > For SoC intergration, every t-head CPU would give a reset signal, and
> > SoC customer could intergrate them into their own reset control
> > register, generally, every bit indicate a reset signal. Some of them
> > would combine it with their SoC bus reset signal, so we provide a
> > flexiable/undefined setting value here.
>
> So TL;DR, highly per-soc specific value, that you cannot explain since
> it could mean completely different things, with completely different
> behaviour (what registers it even writes to, which buses are affected)
>
> I'm sorry, but I don't see why this shouldn't be split away from the csr
> stuff completely, and become a "real" reset controller - especially if
> different SoCs using your cores are going to be doing wildly different
> things.
>
> Cheers,
> Conor.
>
> > This has been implemented in opensbi, and we have used it many years :)
> > https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> >
> > val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
> > if (len > 0 && val) {
> > p = (void *)(ulong)fdt64_to_cpu(*val);
> >
> > val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
> > if (len > 0 && val_w) {
> > tmp = fdt32_to_cpu(*val_w);
> > tmp |= readl(p);
> > writel(tmp, p);
> > }
> > }
>


-- 
Best Regards
 Guo Ren


From guoren at kernel.org  Tue Jun 13 18:17:20 2023
From: guoren at kernel.org (Guo Ren)
Date: Wed, 14 Jun 2023 09:17:20 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <20230613-define-constrict-7608d966e0e8@spud>
References: <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud> <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud>
Message-ID: <CAJF2gTTTETPnbmP3KAMPCHTKdDpJ8kzaXrwkk36j5LcEYG_H1g@mail.gmail.com>

On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
>
> Hey Guo Ren,
>
> On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > format of the reset controller:
> > > >
> > > >                reset-controller at ffff019050 {
> > > >                        compatible = "thead,cpu-reset";
>
> Also, please just add the soc-specific compatibles even if the driver
> will bind against the most common form of it.
compatible = "thead,th1520-cpu-reset";

Correct?

>
> > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > 0xff015004 0x0 0x0>;
> > > >                        reset-ctrl = <0x1c>;
> > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > 0x7c5 0x7cc 0x7ce>;
>
> To be honest, I don't actually understand why "clone-csrs" is even part
> of this "cpu-reset" node. It seems to serve a different purpose to
> something that could take various parts of the SoC out of reset.
> IMO, the "clone-csrs" stuff is something that should be done based on
> the soc-level compatible, and not related to the "cpu-reset" node at
> all, which (given the below) sounds more and more like a regular reset
> controller.
>
>
> > > > The reset-ctrl is used to control different parts of soc, generally, a
> > > > bit indicates a reset signal (a core/a interconnect/a subsystem).
> > >
> > > So what is "reset-ctrl"? Values to write into a register? A register
> > > address?
> >
> > It's a values, and every bit indicate a reset signal.
> >
> > > Should this stuff be represented as a proper reset controller, with a
> > > "resets" property in each of the controlled nodes w/ a phandle + index?
> > > It's hard to say with your explanation here :/ Is there some
> > > documentation in English that I could look at? Unfortunately that's only
> > > language I speak that anyone writes technical docs in.
> > Sorry, there is no exact document about reset-ctrl, becasue every SoC
> > customers has some little difference here.
> >
> > For SoC intergration, every t-head CPU would give a reset signal, and
> > SoC customer could intergrate them into their own reset control
> > register, generally, every bit indicate a reset signal. Some of them
> > would combine it with their SoC bus reset signal, so we provide a
> > flexiable/undefined setting value here.
>
> So TL;DR, highly per-soc specific value, that you cannot explain since
> it could mean completely different things, with completely different
> behaviour (what registers it even writes to, which buses are affected)
>
> I'm sorry, but I don't see why this shouldn't be split away from the csr
> stuff completely, and become a "real" reset controller - especially if
> different SoCs using your cores are going to be doing wildly different
> things.
>
> Cheers,
> Conor.
>
> > This has been implemented in opensbi, and we have used it many years :)
> > https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> >
> > val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
> > if (len > 0 && val) {
> > p = (void *)(ulong)fdt64_to_cpu(*val);
> >
> > val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
> > if (len > 0 && val_w) {
> > tmp = fdt32_to_cpu(*val_w);
> > tmp |= readl(p);
> > writel(tmp, p);
> > }
> > }
>


-- 
Best Regards
 Guo Ren


From jrtc27 at jrtc27.com  Tue Jun 13 18:25:41 2023
From: jrtc27 at jrtc27.com (Jessica Clarke)
Date: Wed, 14 Jun 2023 02:25:41 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTRFbh5vV0ktD43z_Nhj04e=FKWtdnO+9jyYyjwQO4tbiw@mail.gmail.com>
References: <20230523094649.4100554-1-guoren@kernel.org>
 <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud>
 <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy>
 <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud>
 <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com>
 <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>
 <F519491B-325E-4B8D-961C-FC8965895BA3@jrtc27.com>
 <CAJF2gTRFbh5vV0ktD43z_Nhj04e=FKWtdnO+9jyYyjwQO4tbiw@mail.gmail.com>
Message-ID: <858958E3-78A5-460F-BE5D-EFF9D8628C1B@jrtc27.com>

On 14 Jun 2023, at 02:07, Guo Ren <guoren at kernel.org> wrote:
> 
> On Tue, Jun 13, 2023 at 10:43?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>> 
>> On 13 Jun 2023, at 03:21, Guo Ren <guoren at kernel.org> wrote:
>>> 
>>> On Mon, Jun 12, 2023 at 9:05?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>>>> 
>>>> On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
>>>>> 
>>>>> Hi Conor,
>>>>> 
>>>>> Jisheng Zhang would update the Linux yaml patch, here is the final dts
>>>>> format of the reset controller:
>>>>> 
>>>>>             reset-controller at ffff019050 {
>>>>>                     compatible = "thead,cpu-reset";
>>>>>                     reg = <0xff 0xff019050 0x0 0x4>, <0xff
>>>>> 0xff015004 0x0 0x0>;
>>>>>                     reset-ctrl = <0x1c>;
>>>>>                     clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
>>>> 
>>>> This is pretty horrible, there?s no indirect CSR read/write
>>>> instruction, so what are you expecting drivers to do with this? Have a
>>> We've done it in the opensbi:
>>> https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
>>> 
>>> A lot of SoC customers would intergrate their own CSRs though our rtl
>>> code interface, these CSRs are initilized in their primary hart in
>>> early boot stage / jtag gdbinit script, the secondary harts just copy
>>> the CSRs' values from boot hart. That means we could provide a unified
>>> way to all customer.
>>> 
>>>> big switch statement for every possible CSR?
>>> We needn't big switch statement, boot hart store the csrs setting
>>> codes in the memory, and secondary harts excute them to set the csrs.
>>> Here is the code snippet:
>>> 
>>> struct custom_csr custom_csr[MAX_CUSTOM_CSR];
>>> 
>>> #define CSR_OPCODE 0x39073
>>> static void clone_csrs(int cnt)
>>> {
>>> unsigned long i;
>>> 
>>> for (i = 0; i < cnt; i++) {
>>> /* Write csr BIT[31 - 20] to stub */
>>> __reset_thead_csr_stub[3*i + 1] = CSR_OPCODE | (custom_csr[i].index << 20);
>>> 
>>> /* Mask csr BIT[31 - 20] */
>>> *(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
>>> smp_mb();
>>> 
>>> /* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
>>> *(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
>>> smp_mb();
>>> 
>>> RISCV_FENCE_I;
>>> 
>>> custom_csr[i].value = __fdt_reset_thead_csrr();
>>> }
>> 
>> So you want your highly-privileged firmware to be dynamically
>> generating code, with the ability to have a WX mapping in the
>> first place?
> We don't expect WX mapping, but the current fdt_reset_init is after
> the pmp config. I need to move it into early_init. Thx for pointing it
> out.

So you didn?t test your code?

Besides, my point was not about correctness, but about the security
concerns that come with generating code at run time. If you don?t need
to do it, don?t.

Jess

>>> }
>>> ==========
>>> 
>>> /* Prepare clone csrs */
>>> val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
>>> if (len > 0 && val_w) {
>>> int cnt;
>>> 
>>> cnt = len / sizeof(fdt32_t);
>>> if (cnt > MAX_CUSTOM_CSR)
>>> sbi_hart_hang();
>>> 
>>> for (i = 0; i < cnt; i++) {
>>> custom_csr[i].index = fdt32_to_cpu(val_w[i]);
>>> }
>>> 
>>> if (cnt)
>>> clone_csrs(cnt); // prepare the secondary harts' excution code
>>> }
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>>> 
>>>> Jess
>>>> 
>>>>> 0x7c5 0x7cc 0x7ce>;
>>>>>              };
>>>>> 
>>>>> The reset-ctrl is used to control different parts of soc, generally, a
>>>>> bit indicates a reset signal (a core/a interconnect/a subsystem).
>>>>> 
>>>>> On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
>>>>>> 
>>>>>> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
>>>>>>> 
>>>>>>>> So it could be "thead,cpu-reset", okay?
>>>>>>> 
>>>>>>> As a generic fallback compatible.
>>>>>>> 
>>>>>>>> Actually, our core could let SoC vendors define their own custom
>>>>>>>> CSRs/custom reset values of CSRs, so we don't know what would be added
>>>>>>>> in the future. Put a array in dts instead of hard-code table is much
>>>>>>>> more flexiblity.
>>>>>>> 
>>>>>>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
>>>>>> Yes, that is what we want. th1520 is a example.
>>>>>> 
>>>>>> Thanks for the review and correction! Your help is greatly appreciated
>>>>>> in improving th1520 upstream.
>>>>>> 
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Conor.
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> --
>>>>>> Best Regards
>>>>>> Guo Ren
>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> Best Regards
>>>>> Guo Ren
>>>> 
>>> 
>>> 
>>> --
>>> Best Regards
>>> Guo Ren
>> 
>> 
> 
> 
> --
> Best Regards
> Guo Ren




From conor at kernel.org  Tue Jun 13 12:36:24 2023
From: conor at kernel.org (Conor Dooley)
Date: Tue, 13 Jun 2023 20:36:24 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
References: <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud>
 <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud>
 <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
Message-ID: <20230613-define-constrict-7608d966e0e8@spud>

Hey Guo Ren,

On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > format of the reset controller:
> > >
> > >                reset-controller at ffff019050 {
> > >                        compatible = "thead,cpu-reset";

Also, please just add the soc-specific compatibles even if the driver
will bind against the most common form of it.

> > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > 0xff015004 0x0 0x0>;
> > >                        reset-ctrl = <0x1c>;
> > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > 0x7c5 0x7cc 0x7ce>;

To be honest, I don't actually understand why "clone-csrs" is even part
of this "cpu-reset" node. It seems to serve a different purpose to
something that could take various parts of the SoC out of reset.
IMO, the "clone-csrs" stuff is something that should be done based on
the soc-level compatible, and not related to the "cpu-reset" node at
all, which (given the below) sounds more and more like a regular reset
controller.


> > > The reset-ctrl is used to control different parts of soc, generally, a
> > > bit indicates a reset signal (a core/a interconnect/a subsystem).
> >
> > So what is "reset-ctrl"? Values to write into a register? A register
> > address?
> 
> It's a values, and every bit indicate a reset signal.
> 
> > Should this stuff be represented as a proper reset controller, with a
> > "resets" property in each of the controlled nodes w/ a phandle + index?
> > It's hard to say with your explanation here :/ Is there some
> > documentation in English that I could look at? Unfortunately that's only
> > language I speak that anyone writes technical docs in.
> Sorry, there is no exact document about reset-ctrl, becasue every SoC
> customers has some little difference here.
> 
> For SoC intergration, every t-head CPU would give a reset signal, and
> SoC customer could intergrate them into their own reset control
> register, generally, every bit indicate a reset signal. Some of them
> would combine it with their SoC bus reset signal, so we provide a
> flexiable/undefined setting value here.

So TL;DR, highly per-soc specific value, that you cannot explain since
it could mean completely different things, with completely different
behaviour (what registers it even writes to, which buses are affected)

I'm sorry, but I don't see why this shouldn't be split away from the csr
stuff completely, and become a "real" reset controller - especially if
different SoCs using your cores are going to be doing wildly different
things.

Cheers,
Conor.

> This has been implemented in opensbi, and we have used it many years :)
> https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> 
> val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
> if (len > 0 && val) {
> p = (void *)(ulong)fdt64_to_cpu(*val);
> 
> val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
> if (len > 0 && val_w) {
> tmp = fdt32_to_cpu(*val_w);
> tmp |= readl(p);
> writel(tmp, p);
> }
> }

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/opensbi/attachments/20230613/aafd8ad0/attachment.sig>

From anup at brainfault.org  Tue Jun 13 22:57:24 2023
From: anup at brainfault.org (Anup Patel)
Date: Wed, 14 Jun 2023 11:27:24 +0530
Subject: [PATCH 0/2] OpenSBI logo and copyright update
In-Reply-To: <20230611040857.51858-1-apatel@ventanamicro.com>
References: <20230611040857.51858-1-apatel@ventanamicro.com>
Message-ID: <CAAhSdy1vqQ6EpJNgS+=dy-aYgPt=cV=+=_fayYsMn5dAf-55PQ@mail.gmail.com>

On Sun, Jun 11, 2023 at 9:39?AM Anup Patel <apatel at ventanamicro.com> wrote:
>
> The OpenSBI project does have an official logo which was designed
> few months back. This logo is reviewed and approved by RISC-V
> international. In fact, some of the RISC-V international slides
> already use the official OpenSBI logo.
>
> We add the official logo to the OpenSBI sources so that anyone can:
> * Use it in presentations
> * Create laptop stickers
> * ... and more ...
>
> We also update project copyright information in the top-level
> README.md.
>
> These patches can also be found in logo_v1 branch at:
> https://github.com/avpatel/opensbi.git
>
> Anup Patel (2):
>   docs: Add OpenSBI logo and use it in the top-level README.md
>   README.md: Improve project copyright information

Applied this series to the riscv/opensbi repo.

Regards,
Anup

>
>  README.md                               |   8 ++++++--
>  docs/riscv_opensbi_logo_final_color.png | Bin 0 -> 7758 bytes
>  docs/riscv_opensbi_logo_final_grey.png  | Bin 0 -> 9159 bytes
>  3 files changed, 6 insertions(+), 2 deletions(-)
>  create mode 100644 docs/riscv_opensbi_logo_final_color.png
>  create mode 100644 docs/riscv_opensbi_logo_final_grey.png
>
> --
> 2.34.1
>


From anup at brainfault.org  Tue Jun 13 23:04:00 2023
From: anup at brainfault.org (Anup Patel)
Date: Wed, 14 Jun 2023 11:34:00 +0530
Subject: Upcoming OpenSBI v1.3 release
Message-ID: <CAAhSdy0VoEt9UyD7ZbdW_eUu1p-WOE4gZaoCDfb5JMV9qs-Rnw@mail.gmail.com>

Hi All,

We are close to the OpenSBI v1.3 release. I plan to complete this
release by the end of next week (i.e. 23rd or 24th June 2023).

Until the release happens, I will be merging patches only fixes. Also,
I request everyone to test the latest OpenSBI on their RISC-V platforms.

Thanks & Regards,
Anup


From alexghiti at rivosinc.com  Wed Jun 14 01:20:39 2023
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Wed, 14 Jun 2023 10:20:39 +0200
Subject: [PATCH -fixes] platform/lib: Set no-map attribute on all PMP regions
Message-ID: <20230614082039.484666-1-alexghiti@rivosinc.com>

This reverts commit 6966ad0abe70 ("platform/lib: Allow the OS to map the
regions that are protected by PMP").

It was thought at the time of this commit that allowing the kernel to map
PMP protected regions was safe but it is actually not: for example, the
hibernation process will try to access any linear mapping page and then
will fault on such mapped PMP regions [1]. Another issue is that the
device tree specification [2] states that a !no-map region must be
declared as EfiBootServicesData/Code in the EFI memory map which would make
the PMP protected regions reclaimable by the kernel. And to circumvent
this, RISC-V edk2 diverges from the DT specification to declare those
regions as EfiReserved.

The no-map attribute was removed to allow the kernel to use hugepages
larger than 2MB to map the linear mapping to improve the performance but
actually a recent talk from Mike Rapoport [3] stated that the
performance benefit was marginal.

For all those reasons, let's mark all the PMP protected regions as "no-map".

[1] https://lore.kernel.org/linux-riscv/CAAYs2=gQvkhTeioMmqRDVGjdtNF_vhB+vm_1dHJxPNi75YDQ_Q at mail.gmail.com/
[2] "3.5.4 /reserved-memory and UEFI" https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4-rc1/devicetree-specification-v0.4-rc1.pdf
[3] https://lwn.net/Articles/931406/

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 include/sbi_utils/fdt/fdt_fixup.h | 14 ---------
 lib/utils/fdt/fdt_fixup.c         | 49 +++++++------------------------
 platform/generic/sifive/fu540.c   | 13 --------
 3 files changed, 10 insertions(+), 66 deletions(-)

diff --git a/include/sbi_utils/fdt/fdt_fixup.h b/include/sbi_utils/fdt/fdt_fixup.h
index cab3f0f..ecd55a7 100644
--- a/include/sbi_utils/fdt/fdt_fixup.h
+++ b/include/sbi_utils/fdt/fdt_fixup.h
@@ -93,20 +93,6 @@ void fdt_plic_fixup(void *fdt);
  */
 int fdt_reserved_memory_fixup(void *fdt);
 
-/**
- * Fix up the reserved memory subnodes in the device tree
- *
- * This routine adds the no-map property to the reserved memory subnodes so
- * that the OS does not map those PMP protected memory regions.
- *
- * Platform codes must call this helper in their final_init() after fdt_fixups()
- * if the OS should not map the PMP protected reserved regions.
- *
- * @param fdt: device tree blob
- * @return zero on success and -ve on failure
- */
-int fdt_reserved_memory_nomap_fixup(void *fdt);
-
 /**
  * General device tree fix-up
  *
diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
index ae6be00..e213ded 100644
--- a/lib/utils/fdt/fdt_fixup.c
+++ b/lib/utils/fdt/fdt_fixup.c
@@ -210,7 +210,7 @@ void fdt_plic_fixup(void *fdt)
 
 static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
 				       unsigned long size, int index,
-				       int parent, bool no_map)
+				       int parent)
 {
 	int na = fdt_address_cells(fdt, 0);
 	int ns = fdt_size_cells(fdt, 0);
@@ -239,16 +239,14 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
 	if (subnode < 0)
 		return subnode;
 
-	if (no_map) {
-		/*
-		 * Tell operating system not to create a virtual
-		 * mapping of the region as part of its standard
-		 * mapping of system memory.
-		 */
-		err = fdt_setprop_empty(fdt, subnode, "no-map");
-		if (err < 0)
-			return err;
-	}
+	/*
+	 * Tell operating system not to create a virtual
+	 * mapping of the region as part of its standard
+	 * mapping of system memory.
+	 */
+	err = fdt_setprop_empty(fdt, subnode, "no-map");
+	if (err < 0)
+		return err;
 
 	/* encode the <reg> property value */
 	val = reg;
@@ -286,7 +284,6 @@ int fdt_reserved_memory_fixup(void *fdt)
 {
 	struct sbi_domain_memregion *reg;
 	struct sbi_domain *dom = sbi_domain_thishart_ptr();
-	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 	unsigned long filtered_base[PMP_COUNT] = { 0 };
 	unsigned char filtered_order[PMP_COUNT] = { 0 };
 	unsigned long addr, size;
@@ -382,33 +379,7 @@ int fdt_reserved_memory_fixup(void *fdt)
 	for (j = 0; j < i; j++) {
 		addr = filtered_base[j];
 		size = 1UL << filtered_order[j];
-		fdt_resv_memory_update_node(fdt, addr, size, j, parent,
-					    (sbi_hart_pmp_count(scratch))
-					    ? false : true);
-	}
-
-	return 0;
-}
-
-int fdt_reserved_memory_nomap_fixup(void *fdt)
-{
-	int parent, subnode;
-	int err;
-
-	/* Locate the reserved memory node */
-	parent = fdt_path_offset(fdt, "/reserved-memory");
-	if (parent < 0)
-		return parent;
-
-	fdt_for_each_subnode(subnode, fdt, parent) {
-		/*
-		 * Tell operating system not to create a virtual
-		 * mapping of the region as part of its standard
-		 * mapping of system memory.
-		 */
-		err = fdt_setprop_empty(fdt, subnode, "no-map");
-		if (err < 0)
-			return err;
+		fdt_resv_memory_update_node(fdt, addr, size, j, parent);
 	}
 
 	return 0;
diff --git a/platform/generic/sifive/fu540.c b/platform/generic/sifive/fu540.c
index 08f7bfc..b980f44 100644
--- a/platform/generic/sifive/fu540.c
+++ b/platform/generic/sifive/fu540.c
@@ -20,18 +20,6 @@ static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
 	return 0;
 }
 
-static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
-{
-	/*
-	 * SiFive Freedom U540 has an erratum that prevents S-mode software
-	 * to access a PMP protected region using 1GB page table mapping, so
-	 * always add the no-map attribute on this platform.
-	 */
-	fdt_reserved_memory_nomap_fixup(fdt);
-
-	return 0;
-}
-
 static const struct fdt_match sifive_fu540_match[] = {
 	{ .compatible = "sifive,fu540" },
 	{ .compatible = "sifive,fu540g" },
@@ -43,5 +31,4 @@ static const struct fdt_match sifive_fu540_match[] = {
 const struct platform_override sifive_fu540 = {
 	.match_table = sifive_fu540_match,
 	.tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
-	.fdt_fixup = sifive_fu540_fdt_fixup,
 };
-- 
2.39.2



From atishp at atishpatra.org  Thu Jun 15 01:20:30 2023
From: atishp at atishpatra.org (Atish Patra)
Date: Thu, 15 Jun 2023 01:20:30 -0700
Subject: [PATCH -fixes] platform/lib: Set no-map attribute on all PMP regions
In-Reply-To: <20230614082039.484666-1-alexghiti@rivosinc.com>
References: <20230614082039.484666-1-alexghiti@rivosinc.com>
Message-ID: <CAOnJCU+uhSDe8AWDPdEfYDSfgNaAuPzNwtBLHGQgv6FPbdd5pA@mail.gmail.com>

On Wed, Jun 14, 2023 at 1:21?AM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> This reverts commit 6966ad0abe70 ("platform/lib: Allow the OS to map the
> regions that are protected by PMP").
>
> It was thought at the time of this commit that allowing the kernel to map
> PMP protected regions was safe but it is actually not: for example, the
> hibernation process will try to access any linear mapping page and then
> will fault on such mapped PMP regions [1]. Another issue is that the
> device tree specification [2] states that a !no-map region must be
> declared as EfiBootServicesData/Code in the EFI memory map which would make
> the PMP protected regions reclaimable by the kernel. And to circumvent
> this, RISC-V edk2 diverges from the DT specification to declare those
> regions as EfiReserved.
>
> The no-map attribute was removed to allow the kernel to use hugepages
> larger than 2MB to map the linear mapping to improve the performance but
> actually a recent talk from Mike Rapoport [3] stated that the
> performance benefit was marginal.
>
> For all those reasons, let's mark all the PMP protected regions as "no-map".
>
> [1] https://lore.kernel.org/linux-riscv/CAAYs2=gQvkhTeioMmqRDVGjdtNF_vhB+vm_1dHJxPNi75YDQ_Q at mail.gmail.com/
> [2] "3.5.4 /reserved-memory and UEFI" https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4-rc1/devicetree-specification-v0.4-rc1.pdf
> [3] https://lwn.net/Articles/931406/
>
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> ---
>  include/sbi_utils/fdt/fdt_fixup.h | 14 ---------
>  lib/utils/fdt/fdt_fixup.c         | 49 +++++++------------------------
>  platform/generic/sifive/fu540.c   | 13 --------
>  3 files changed, 10 insertions(+), 66 deletions(-)
>
> diff --git a/include/sbi_utils/fdt/fdt_fixup.h b/include/sbi_utils/fdt/fdt_fixup.h
> index cab3f0f..ecd55a7 100644
> --- a/include/sbi_utils/fdt/fdt_fixup.h
> +++ b/include/sbi_utils/fdt/fdt_fixup.h
> @@ -93,20 +93,6 @@ void fdt_plic_fixup(void *fdt);
>   */
>  int fdt_reserved_memory_fixup(void *fdt);
>
> -/**
> - * Fix up the reserved memory subnodes in the device tree
> - *
> - * This routine adds the no-map property to the reserved memory subnodes so
> - * that the OS does not map those PMP protected memory regions.
> - *
> - * Platform codes must call this helper in their final_init() after fdt_fixups()
> - * if the OS should not map the PMP protected reserved regions.
> - *
> - * @param fdt: device tree blob
> - * @return zero on success and -ve on failure
> - */
> -int fdt_reserved_memory_nomap_fixup(void *fdt);
> -
>  /**
>   * General device tree fix-up
>   *
> diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
> index ae6be00..e213ded 100644
> --- a/lib/utils/fdt/fdt_fixup.c
> +++ b/lib/utils/fdt/fdt_fixup.c
> @@ -210,7 +210,7 @@ void fdt_plic_fixup(void *fdt)
>
>  static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
>                                        unsigned long size, int index,
> -                                      int parent, bool no_map)
> +                                      int parent)
>  {
>         int na = fdt_address_cells(fdt, 0);
>         int ns = fdt_size_cells(fdt, 0);
> @@ -239,16 +239,14 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
>         if (subnode < 0)
>                 return subnode;
>
> -       if (no_map) {
> -               /*
> -                * Tell operating system not to create a virtual
> -                * mapping of the region as part of its standard
> -                * mapping of system memory.
> -                */
> -               err = fdt_setprop_empty(fdt, subnode, "no-map");
> -               if (err < 0)
> -                       return err;
> -       }
> +       /*
> +        * Tell operating system not to create a virtual
> +        * mapping of the region as part of its standard
> +        * mapping of system memory.
> +        */
> +       err = fdt_setprop_empty(fdt, subnode, "no-map");
> +       if (err < 0)
> +               return err;
>
>         /* encode the <reg> property value */
>         val = reg;
> @@ -286,7 +284,6 @@ int fdt_reserved_memory_fixup(void *fdt)
>  {
>         struct sbi_domain_memregion *reg;
>         struct sbi_domain *dom = sbi_domain_thishart_ptr();
> -       struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
>         unsigned long filtered_base[PMP_COUNT] = { 0 };
>         unsigned char filtered_order[PMP_COUNT] = { 0 };
>         unsigned long addr, size;
> @@ -382,33 +379,7 @@ int fdt_reserved_memory_fixup(void *fdt)
>         for (j = 0; j < i; j++) {
>                 addr = filtered_base[j];
>                 size = 1UL << filtered_order[j];
> -               fdt_resv_memory_update_node(fdt, addr, size, j, parent,
> -                                           (sbi_hart_pmp_count(scratch))
> -                                           ? false : true);
> -       }
> -
> -       return 0;
> -}
> -
> -int fdt_reserved_memory_nomap_fixup(void *fdt)
> -{
> -       int parent, subnode;
> -       int err;
> -
> -       /* Locate the reserved memory node */
> -       parent = fdt_path_offset(fdt, "/reserved-memory");
> -       if (parent < 0)
> -               return parent;
> -
> -       fdt_for_each_subnode(subnode, fdt, parent) {
> -               /*
> -                * Tell operating system not to create a virtual
> -                * mapping of the region as part of its standard
> -                * mapping of system memory.
> -                */
> -               err = fdt_setprop_empty(fdt, subnode, "no-map");
> -               if (err < 0)
> -                       return err;
> +               fdt_resv_memory_update_node(fdt, addr, size, j, parent);
>         }
>
>         return 0;
> diff --git a/platform/generic/sifive/fu540.c b/platform/generic/sifive/fu540.c
> index 08f7bfc..b980f44 100644
> --- a/platform/generic/sifive/fu540.c
> +++ b/platform/generic/sifive/fu540.c
> @@ -20,18 +20,6 @@ static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
>         return 0;
>  }
>
> -static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
> -{
> -       /*
> -        * SiFive Freedom U540 has an erratum that prevents S-mode software
> -        * to access a PMP protected region using 1GB page table mapping, so
> -        * always add the no-map attribute on this platform.
> -        */
> -       fdt_reserved_memory_nomap_fixup(fdt);
> -
> -       return 0;
> -}
> -
>  static const struct fdt_match sifive_fu540_match[] = {
>         { .compatible = "sifive,fu540" },
>         { .compatible = "sifive,fu540g" },
> @@ -43,5 +31,4 @@ static const struct fdt_match sifive_fu540_match[] = {
>  const struct platform_override sifive_fu540 = {
>         .match_table = sifive_fu540_match,
>         .tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
> -       .fdt_fixup = sifive_fu540_fdt_fixup,
>  };
> --
> 2.39.2
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


Reviewed-by: Atish Patra <atishp at rivosinc.com>

-- 
Regards,
Atish


From wxjstz at 126.com  Thu Jun 15 02:25:12 2023
From: wxjstz at 126.com (Xiang W)
Date: Thu, 15 Jun 2023 17:25:12 +0800
Subject: [PATCH -fixes] platform/lib: Set no-map attribute on all PMP
 regions
In-Reply-To: <20230614082039.484666-1-alexghiti@rivosinc.com>
References: <20230614082039.484666-1-alexghiti@rivosinc.com>
Message-ID: <6a9e5b21976371a4a90e2471765ca1aea1dd4f37.camel@126.com>

? 2023-06-14???? 10:20 +0200?Alexandre Ghiti???
> This reverts commit 6966ad0abe70 ("platform/lib: Allow the OS to map the
> regions that are protected by PMP").
> 
> It was thought at the time of this commit that allowing the kernel to map
> PMP protected regions was safe but it is actually not: for example, the
> hibernation process will try to access any linear mapping page and then
> will fault on such mapped PMP regions [1]. Another issue is that the
> device tree specification [2] states that a !no-map region must be
> declared as EfiBootServicesData/Code in the EFI memory map which would make
> the PMP protected regions reclaimable by the kernel. And to circumvent
> this, RISC-V edk2 diverges from the DT specification to declare those
> regions as EfiReserved.
> 
> The no-map attribute was removed to allow the kernel to use hugepages
> larger than 2MB to map the linear mapping to improve the performance but
> actually a recent talk from Mike Rapoport [3] stated that the
> performance benefit was marginal.
> 
> For all those reasons, let's mark all the PMP protected regions as "no-map".
> 
> [1] https://lore.kernel.org/linux-riscv/CAAYs2=gQvkhTeioMmqRDVGjdtNF_vhB+vm_1dHJxPNi75YDQ_Q at mail.gmail.com/
> [2] "3.5.4 /reserved-memory and UEFI"
> https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4-rc1/devicetree-specification-v0.4-rc1.pdf
> [3] https://lwn.net/Articles/931406/
> 
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Look good to me.

Reviewed-by: Xiang W <wxjstz at 126.com>
> ---
> ?include/sbi_utils/fdt/fdt_fixup.h | 14 ---------
> ?lib/utils/fdt/fdt_fixup.c???????? | 49 +++++++------------------------
> ?platform/generic/sifive/fu540.c?? | 13 --------
> ?3 files changed, 10 insertions(+), 66 deletions(-)
> 
> diff --git a/include/sbi_utils/fdt/fdt_fixup.h b/include/sbi_utils/fdt/fdt_fixup.h
> index cab3f0f..ecd55a7 100644
> --- a/include/sbi_utils/fdt/fdt_fixup.h
> +++ b/include/sbi_utils/fdt/fdt_fixup.h
> @@ -93,20 +93,6 @@ void fdt_plic_fixup(void *fdt);
> ? */
> ?int fdt_reserved_memory_fixup(void *fdt);
> ?
> -/**
> - * Fix up the reserved memory subnodes in the device tree
> - *
> - * This routine adds the no-map property to the reserved memory subnodes so
> - * that the OS does not map those PMP protected memory regions.
> - *
> - * Platform codes must call this helper in their final_init() after fdt_fixups()
> - * if the OS should not map the PMP protected reserved regions.
> - *
> - * @param fdt: device tree blob
> - * @return zero on success and -ve on failure
> - */
> -int fdt_reserved_memory_nomap_fixup(void *fdt);
> -
> ?/**
> ? * General device tree fix-up
> ? *
> diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
> index ae6be00..e213ded 100644
> --- a/lib/utils/fdt/fdt_fixup.c
> +++ b/lib/utils/fdt/fdt_fixup.c
> @@ -210,7 +210,7 @@ void fdt_plic_fixup(void *fdt)
> ?
> ?static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
> ?????????????????????????????????????? unsigned long size, int index,
> -????????????????????????????????????? int parent, bool no_map)
> +????????????????????????????????????? int parent)
> ?{
> ????????int na = fdt_address_cells(fdt, 0);
> ????????int ns = fdt_size_cells(fdt, 0);
> @@ -239,16 +239,14 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
> ????????if (subnode < 0)
> ????????????????return subnode;
> ?
> -???????if (no_map) {
> -???????????????/*
> -??????????????? * Tell operating system not to create a virtual
> -??????????????? * mapping of the region as part of its standard
> -??????????????? * mapping of system memory.
> -??????????????? */
> -???????????????err = fdt_setprop_empty(fdt, subnode, "no-map");
> -???????????????if (err < 0)
> -???????????????????????return err;
> -???????}
> +???????/*
> +??????? * Tell operating system not to create a virtual
> +??????? * mapping of the region as part of its standard
> +??????? * mapping of system memory.
> +??????? */
> +???????err = fdt_setprop_empty(fdt, subnode, "no-map");
> +???????if (err < 0)
> +???????????????return err;
> ?
> ????????/* encode the <reg> property value */
> ????????val = reg;
> @@ -286,7 +284,6 @@ int fdt_reserved_memory_fixup(void *fdt)
> ?{
> ????????struct sbi_domain_memregion *reg;
> ????????struct sbi_domain *dom = sbi_domain_thishart_ptr();
> -???????struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> ????????unsigned long filtered_base[PMP_COUNT] = { 0 };
> ????????unsigned char filtered_order[PMP_COUNT] = { 0 };
> ????????unsigned long addr, size;
> @@ -382,33 +379,7 @@ int fdt_reserved_memory_fixup(void *fdt)
> ????????for (j = 0; j < i; j++) {
> ????????????????addr = filtered_base[j];
> ????????????????size = 1UL << filtered_order[j];
> -???????????????fdt_resv_memory_update_node(fdt, addr, size, j, parent,
> -?????????????????????????????????????????? (sbi_hart_pmp_count(scratch))
> -?????????????????????????????????????????? ? false : true);
> -???????}
> -
> -???????return 0;
> -}
> -
> -int fdt_reserved_memory_nomap_fixup(void *fdt)
> -{
> -???????int parent, subnode;
> -???????int err;
> -
> -???????/* Locate the reserved memory node */
> -???????parent = fdt_path_offset(fdt, "/reserved-memory");
> -???????if (parent < 0)
> -???????????????return parent;
> -
> -???????fdt_for_each_subnode(subnode, fdt, parent) {
> -???????????????/*
> -??????????????? * Tell operating system not to create a virtual
> -??????????????? * mapping of the region as part of its standard
> -??????????????? * mapping of system memory.
> -??????????????? */
> -???????????????err = fdt_setprop_empty(fdt, subnode, "no-map");
> -???????????????if (err < 0)
> -???????????????????????return err;
> +???????????????fdt_resv_memory_update_node(fdt, addr, size, j, parent);
> ????????}
> ?
> ????????return 0;
> diff --git a/platform/generic/sifive/fu540.c b/platform/generic/sifive/fu540.c
> index 08f7bfc..b980f44 100644
> --- a/platform/generic/sifive/fu540.c
> +++ b/platform/generic/sifive/fu540.c
> @@ -20,18 +20,6 @@ static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
> ????????return 0;
> ?}
> ?
> -static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
> -{
> -???????/*
> -??????? * SiFive Freedom U540 has an erratum that prevents S-mode software
> -??????? * to access a PMP protected region using 1GB page table mapping, so
> -??????? * always add the no-map attribute on this platform.
> -??????? */
> -???????fdt_reserved_memory_nomap_fixup(fdt);
> -
> -???????return 0;
> -}
> -
> ?static const struct fdt_match sifive_fu540_match[] = {
> ????????{ .compatible = "sifive,fu540" },
> ????????{ .compatible = "sifive,fu540g" },
> @@ -43,5 +31,4 @@ static const struct fdt_match sifive_fu540_match[] = {
> ?const struct platform_override sifive_fu540 = {
> ????????.match_table = sifive_fu540_match,
> ????????.tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
> -???????.fdt_fixup = sifive_fu540_fdt_fixup,
> ?};
> -- 
> 2.39.2
> 
> 


From anup at brainfault.org  Thu Jun 15 06:02:45 2023
From: anup at brainfault.org (Anup Patel)
Date: Thu, 15 Jun 2023 18:32:45 +0530
Subject: [PATCH -fixes] platform/lib: Set no-map attribute on all PMP regions
In-Reply-To: <20230614082039.484666-1-alexghiti@rivosinc.com>
References: <20230614082039.484666-1-alexghiti@rivosinc.com>
Message-ID: <CAAhSdy0kBETf_KEc8Ye13EFfwB3rzPHzSvbK+YqJbx1US+dfEw@mail.gmail.com>

On Wed, Jun 14, 2023 at 1:50?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> This reverts commit 6966ad0abe70 ("platform/lib: Allow the OS to map the
> regions that are protected by PMP").
>
> It was thought at the time of this commit that allowing the kernel to map
> PMP protected regions was safe but it is actually not: for example, the
> hibernation process will try to access any linear mapping page and then
> will fault on such mapped PMP regions [1]. Another issue is that the
> device tree specification [2] states that a !no-map region must be
> declared as EfiBootServicesData/Code in the EFI memory map which would make
> the PMP protected regions reclaimable by the kernel. And to circumvent
> this, RISC-V edk2 diverges from the DT specification to declare those
> regions as EfiReserved.
>
> The no-map attribute was removed to allow the kernel to use hugepages
> larger than 2MB to map the linear mapping to improve the performance but
> actually a recent talk from Mike Rapoport [3] stated that the
> performance benefit was marginal.
>
> For all those reasons, let's mark all the PMP protected regions as "no-map".
>
> [1] https://lore.kernel.org/linux-riscv/CAAYs2=gQvkhTeioMmqRDVGjdtNF_vhB+vm_1dHJxPNi75YDQ_Q at mail.gmail.com/
> [2] "3.5.4 /reserved-memory and UEFI" https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4-rc1/devicetree-specification-v0.4-rc1.pdf
> [3] https://lwn.net/Articles/931406/
>
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  include/sbi_utils/fdt/fdt_fixup.h | 14 ---------
>  lib/utils/fdt/fdt_fixup.c         | 49 +++++++------------------------
>  platform/generic/sifive/fu540.c   | 13 --------
>  3 files changed, 10 insertions(+), 66 deletions(-)
>
> diff --git a/include/sbi_utils/fdt/fdt_fixup.h b/include/sbi_utils/fdt/fdt_fixup.h
> index cab3f0f..ecd55a7 100644
> --- a/include/sbi_utils/fdt/fdt_fixup.h
> +++ b/include/sbi_utils/fdt/fdt_fixup.h
> @@ -93,20 +93,6 @@ void fdt_plic_fixup(void *fdt);
>   */
>  int fdt_reserved_memory_fixup(void *fdt);
>
> -/**
> - * Fix up the reserved memory subnodes in the device tree
> - *
> - * This routine adds the no-map property to the reserved memory subnodes so
> - * that the OS does not map those PMP protected memory regions.
> - *
> - * Platform codes must call this helper in their final_init() after fdt_fixups()
> - * if the OS should not map the PMP protected reserved regions.
> - *
> - * @param fdt: device tree blob
> - * @return zero on success and -ve on failure
> - */
> -int fdt_reserved_memory_nomap_fixup(void *fdt);
> -
>  /**
>   * General device tree fix-up
>   *
> diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
> index ae6be00..e213ded 100644
> --- a/lib/utils/fdt/fdt_fixup.c
> +++ b/lib/utils/fdt/fdt_fixup.c
> @@ -210,7 +210,7 @@ void fdt_plic_fixup(void *fdt)
>
>  static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
>                                        unsigned long size, int index,
> -                                      int parent, bool no_map)
> +                                      int parent)
>  {
>         int na = fdt_address_cells(fdt, 0);
>         int ns = fdt_size_cells(fdt, 0);
> @@ -239,16 +239,14 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
>         if (subnode < 0)
>                 return subnode;
>
> -       if (no_map) {
> -               /*
> -                * Tell operating system not to create a virtual
> -                * mapping of the region as part of its standard
> -                * mapping of system memory.
> -                */
> -               err = fdt_setprop_empty(fdt, subnode, "no-map");
> -               if (err < 0)
> -                       return err;
> -       }
> +       /*
> +        * Tell operating system not to create a virtual
> +        * mapping of the region as part of its standard
> +        * mapping of system memory.
> +        */
> +       err = fdt_setprop_empty(fdt, subnode, "no-map");
> +       if (err < 0)
> +               return err;
>
>         /* encode the <reg> property value */
>         val = reg;
> @@ -286,7 +284,6 @@ int fdt_reserved_memory_fixup(void *fdt)
>  {
>         struct sbi_domain_memregion *reg;
>         struct sbi_domain *dom = sbi_domain_thishart_ptr();
> -       struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
>         unsigned long filtered_base[PMP_COUNT] = { 0 };
>         unsigned char filtered_order[PMP_COUNT] = { 0 };
>         unsigned long addr, size;
> @@ -382,33 +379,7 @@ int fdt_reserved_memory_fixup(void *fdt)
>         for (j = 0; j < i; j++) {
>                 addr = filtered_base[j];
>                 size = 1UL << filtered_order[j];
> -               fdt_resv_memory_update_node(fdt, addr, size, j, parent,
> -                                           (sbi_hart_pmp_count(scratch))
> -                                           ? false : true);
> -       }
> -
> -       return 0;
> -}
> -
> -int fdt_reserved_memory_nomap_fixup(void *fdt)
> -{
> -       int parent, subnode;
> -       int err;
> -
> -       /* Locate the reserved memory node */
> -       parent = fdt_path_offset(fdt, "/reserved-memory");
> -       if (parent < 0)
> -               return parent;
> -
> -       fdt_for_each_subnode(subnode, fdt, parent) {
> -               /*
> -                * Tell operating system not to create a virtual
> -                * mapping of the region as part of its standard
> -                * mapping of system memory.
> -                */
> -               err = fdt_setprop_empty(fdt, subnode, "no-map");
> -               if (err < 0)
> -                       return err;
> +               fdt_resv_memory_update_node(fdt, addr, size, j, parent);
>         }
>
>         return 0;
> diff --git a/platform/generic/sifive/fu540.c b/platform/generic/sifive/fu540.c
> index 08f7bfc..b980f44 100644
> --- a/platform/generic/sifive/fu540.c
> +++ b/platform/generic/sifive/fu540.c
> @@ -20,18 +20,6 @@ static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
>         return 0;
>  }
>
> -static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
> -{
> -       /*
> -        * SiFive Freedom U540 has an erratum that prevents S-mode software
> -        * to access a PMP protected region using 1GB page table mapping, so
> -        * always add the no-map attribute on this platform.
> -        */
> -       fdt_reserved_memory_nomap_fixup(fdt);
> -
> -       return 0;
> -}
> -
>  static const struct fdt_match sifive_fu540_match[] = {
>         { .compatible = "sifive,fu540" },
>         { .compatible = "sifive,fu540g" },
> @@ -43,5 +31,4 @@ static const struct fdt_match sifive_fu540_match[] = {
>  const struct platform_override sifive_fu540 = {
>         .match_table = sifive_fu540_match,
>         .tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
> -       .fdt_fixup = sifive_fu540_fdt_fixup,
>  };
> --
> 2.39.2
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From conor.dooley at microchip.com  Tue Jun 13 23:56:14 2023
From: conor.dooley at microchip.com (Conor Dooley)
Date: Wed, 14 Jun 2023 07:56:14 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>
References: <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud>
 <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud>
 <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud>
 <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>
Message-ID: <20230614-coauthor-altitude-5f5fcb23c75c@wendy>

On Wed, Jun 14, 2023 at 09:11:01AM +0800, Guo Ren wrote:
> On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
> > On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > > format of the reset controller:

@Jisheng, iirc this was the only real outstanding thing for your Linux
patchset, if you re-submit without the reset controller this week it
should still be in time for v6.5.

> > > > >                reset-controller at ffff019050 {
> > > > >                        compatible = "thead,cpu-reset";
> >
> > Also, please just add the soc-specific compatibles even if the driver
> > will bind against the most common form of it.
> >
> > > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > > 0xff015004 0x0 0x0>;
> > > > >                        reset-ctrl = <0x1c>;
> > > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > > 0x7c5 0x7cc 0x7ce>;
> >
> > To be honest, I don't actually understand why "clone-csrs" is even part
> > of this "cpu-reset" node. It seems to serve a different purpose to
> > something that could take various parts of the SoC out of reset.
> > IMO, the "clone-csrs" stuff is something that should be done based on
> > the soc-level compatible, and not related to the "cpu-reset" node at
> > all, which (given the below) sounds more and more like a regular reset
> > controller.

> We need to put clone-csrs' execution entry into the reset entry (the
> first reg address).

So, take the first reg out too then, with the clone-csrs bits?

That'd leave you with a "regular" reset controller for bits that reset
various parts of the SoC & the clone-csrs stuff can be its own thing.

What am I missing?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/opensbi/attachments/20230614/257e6f15/attachment.sig>

From guoren at kernel.org  Thu Jun 15 08:32:05 2023
From: guoren at kernel.org (Guo Ren)
Date: Thu, 15 Jun 2023 23:32:05 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <858958E3-78A5-460F-BE5D-EFF9D8628C1B@jrtc27.com>
References: <20230523094649.4100554-1-guoren@kernel.org> <20230523094649.4100554-3-guoren@kernel.org>
 <20230523-manatee-providing-77413fac0c58@spud> <CAJF2gTSR1LzGyzxLWWst+4M_nKWXBA=v8=zY-42-ODGU_aO-Lg@mail.gmail.com>
 <20230524-vertebrae-slip-84584f5bb65b@wendy> <CAJF2gTQPyyi5twqdboo=4t0KgP0RqgOpqd0PX239PQZKC-Z8Uw@mail.gmail.com>
 <20230524-claw-obligate-e4815c3e232b@spud> <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <2B91C2C6-750D-43B5-9E03-B53F07045056@jrtc27.com> <CAJF2gTToZv2bNrpKn2oJx_v_hkYLWsQokC9VniMnd_v2mKuaVg@mail.gmail.com>
 <F519491B-325E-4B8D-961C-FC8965895BA3@jrtc27.com> <CAJF2gTRFbh5vV0ktD43z_Nhj04e=FKWtdnO+9jyYyjwQO4tbiw@mail.gmail.com>
 <858958E3-78A5-460F-BE5D-EFF9D8628C1B@jrtc27.com>
Message-ID: <CAJF2gTSDGmawDjswmQjT3na=AyUAHy2dEamrUC5AHUH0r+bfcg@mail.gmail.com>

On Wed, Jun 14, 2023 at 9:25?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
>
> On 14 Jun 2023, at 02:07, Guo Ren <guoren at kernel.org> wrote:
> >
> > On Tue, Jun 13, 2023 at 10:43?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
> >>
> >> On 13 Jun 2023, at 03:21, Guo Ren <guoren at kernel.org> wrote:
> >>>
> >>> On Mon, Jun 12, 2023 at 9:05?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
> >>>>
> >>>> On 12 Jun 2023, at 01:57, Guo Ren <guoren at kernel.org> wrote:
> >>>>>
> >>>>> Hi Conor,
> >>>>>
> >>>>> Jisheng Zhang would update the Linux yaml patch, here is the final dts
> >>>>> format of the reset controller:
> >>>>>
> >>>>>             reset-controller at ffff019050 {
> >>>>>                     compatible = "thead,cpu-reset";
> >>>>>                     reg = <0xff 0xff019050 0x0 0x4>, <0xff
> >>>>> 0xff015004 0x0 0x0>;
> >>>>>                     reset-ctrl = <0x1c>;
> >>>>>                     clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> >>>>
> >>>> This is pretty horrible, there?s no indirect CSR read/write
> >>>> instruction, so what are you expecting drivers to do with this? Have a
> >>> We've done it in the opensbi:
> >>> https://github.com/riscv-software-src/opensbi/blob/master/lib/utils/reset/fdt_reset_thead.c
> >>>
> >>> A lot of SoC customers would intergrate their own CSRs though our rtl
> >>> code interface, these CSRs are initilized in their primary hart in
> >>> early boot stage / jtag gdbinit script, the secondary harts just copy
> >>> the CSRs' values from boot hart. That means we could provide a unified
> >>> way to all customer.
> >>>
> >>>> big switch statement for every possible CSR?
> >>> We needn't big switch statement, boot hart store the csrs setting
> >>> codes in the memory, and secondary harts excute them to set the csrs.
> >>> Here is the code snippet:
> >>>
> >>> struct custom_csr custom_csr[MAX_CUSTOM_CSR];
> >>>
> >>> #define CSR_OPCODE 0x39073
> >>> static void clone_csrs(int cnt)
> >>> {
> >>> unsigned long i;
> >>>
> >>> for (i = 0; i < cnt; i++) {
> >>> /* Write csr BIT[31 - 20] to stub */
> >>> __reset_thead_csr_stub[3*i + 1] = CSR_OPCODE | (custom_csr[i].index << 20);
> >>>
> >>> /* Mask csr BIT[31 - 20] */
> >>> *(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
> >>> smp_mb();
> >>>
> >>> /* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
> >>> *(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
> >>> smp_mb();
> >>>
> >>> RISCV_FENCE_I;
> >>>
> >>> custom_csr[i].value = __fdt_reset_thead_csrr();
> >>> }
> >>
> >> So you want your highly-privileged firmware to be dynamically
> >> generating code, with the ability to have a WX mapping in the
> >> first place?
> > We don't expect WX mapping, but the current fdt_reset_init is after
> > the pmp config. I need to move it into early_init. Thx for pointing it
> > out.
>
> So you didn?t test your code?
We've used it for 2 years, it could satifies us to deliver our CPU
core to the SoC vendors.

Current pmp didn't support WX mapping for m-mode, we force ARWX for
all memory regions for m-mode. See:

Priv-isa-spec
3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will
succeed; the R/W/X permissions apply only to S and U modes.

>
> Besides, my point was not about correctness, but about the security
> concerns that come with generating code at run time. If you don?t need
> to do it, don?t.
I agree to prevent generating code at run time, but this advice is not
related to my case.
I found my reset_fdt_init is after pmp_configure, and I plan to move
it before it. Next, when we update to ehanced PMP ISA, the root domain
region1 could be real READ & EXECUTE permission, we can froze the text
region.

>
> Jess
>
> >>> }
> >>> ==========
> >>>
> >>> /* Prepare clone csrs */
> >>> val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
> >>> if (len > 0 && val_w) {
> >>> int cnt;
> >>>
> >>> cnt = len / sizeof(fdt32_t);
> >>> if (cnt > MAX_CUSTOM_CSR)
> >>> sbi_hart_hang();
> >>>
> >>> for (i = 0; i < cnt; i++) {
> >>> custom_csr[i].index = fdt32_to_cpu(val_w[i]);
> >>> }
> >>>
> >>> if (cnt)
> >>> clone_csrs(cnt); // prepare the secondary harts' excution code
> >>> }
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>
> >>>> Jess
> >>>>
> >>>>> 0x7c5 0x7cc 0x7ce>;
> >>>>>              };
> >>>>>
> >>>>> The reset-ctrl is used to control different parts of soc, generally, a
> >>>>> bit indicates a reset signal (a core/a interconnect/a subsystem).
> >>>>>
> >>>>> On Thu, May 25, 2023 at 2:06?PM Guo Ren <guoren at kernel.org> wrote:
> >>>>>>
> >>>>>> On Thu, May 25, 2023 at 1:33?PM Conor Dooley <conor at kernel.org> wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On 25 May 2023 04:15:36 IST, Guo Ren <guoren at kernel.org> wrote:
> >>>>>>>
> >>>>>>>> So it could be "thead,cpu-reset", okay?
> >>>>>>>
> >>>>>>> As a generic fallback compatible.
> >>>>>>>
> >>>>>>>> Actually, our core could let SoC vendors define their own custom
> >>>>>>>> CSRs/custom reset values of CSRs, so we don't know what would be added
> >>>>>>>> in the future. Put a array in dts instead of hard-code table is much
> >>>>>>>> more flexiblity.
> >>>>>>>
> >>>>>>> If there's going to be 700 different variations depending on what people do with openc910, then allowing it to be passed sounds like a good idea.
> >>>>>> Yes, that is what we want. th1520 is a example.
> >>>>>>
> >>>>>> Thanks for the review and correction! Your help is greatly appreciated
> >>>>>> in improving th1520 upstream.
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> Conor.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> --
> >>>>>> Best Regards
> >>>>>> Guo Ren
> >>>>>
> >>>>>
> >>>>>
> >>>>> --
> >>>>> Best Regards
> >>>>> Guo Ren
> >>>>
> >>>
> >>>
> >>> --
> >>> Best Regards
> >>> Guo Ren
> >>
> >>
> >
> >
> > --
> > Best Regards
> > Guo Ren
>
>


--
Best Regards
 Guo Ren


From guoren at kernel.org  Thu Jun 15 08:54:38 2023
From: guoren at kernel.org (Guo Ren)
Date: Thu, 15 Jun 2023 23:54:38 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <20230614-coauthor-altitude-5f5fcb23c75c@wendy>
References: <0115F3EA-6071-4876-A50B-CCCB6496FBB6@jrtc27.com>
 <20230524-climate-citrus-4959e052bf56@spud> <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud> <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud> <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>
 <20230614-coauthor-altitude-5f5fcb23c75c@wendy>
Message-ID: <CAJF2gTQHXrEsf=auwSU0bTesin9rXExTD3hgDpsMQPCxMYp4-A@mail.gmail.com>

On Wed, Jun 14, 2023 at 2:56?PM Conor Dooley <conor.dooley at microchip.com> wrote:
>
> On Wed, Jun 14, 2023 at 09:11:01AM +0800, Guo Ren wrote:
> > On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
> > > On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > > > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > > > format of the reset controller:
>
> @Jisheng, iirc this was the only real outstanding thing for your Linux
> patchset, if you re-submit without the reset controller this week it
> should still be in time for v6.5.
I also agree let others go head first, thx Conor.

>
> > > > > >                reset-controller at ffff019050 {
> > > > > >                        compatible = "thead,cpu-reset";
> > >
> > > Also, please just add the soc-specific compatibles even if the driver
> > > will bind against the most common form of it.
> > >
> > > > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > > > 0xff015004 0x0 0x0>;
> > > > > >                        reset-ctrl = <0x1c>;
> > > > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > > > 0x7c5 0x7cc 0x7ce>;
> > >
> > > To be honest, I don't actually understand why "clone-csrs" is even part
> > > of this "cpu-reset" node. It seems to serve a different purpose to
> > > something that could take various parts of the SoC out of reset.
> > > IMO, the "clone-csrs" stuff is something that should be done based on
> > > the soc-level compatible, and not related to the "cpu-reset" node at
> > > all, which (given the below) sounds more and more like a regular reset
> > > controller.
>
> > We need to put clone-csrs' execution entry into the reset entry (the
> > first reg address).
>
> So, take the first reg out too then, with the clone-csrs bits?
>
> That'd leave you with a "regular" reset controller for bits that reset
> various parts of the SoC & the clone-csrs stuff can be its own thing.
>
> What am I missing?

+               tmp = (ulong)&__thead_pre_start_warm;
+               writel(tmp, (char *)(ulong)reg_addr + (i * 8));
+               tmp = (u64)(ulong)&__thead_pre_start_warm >> 32;
+               writel(tmp, (char *)(ulong)reg_addr + (i * 8) + 4);
We write __thead_pre_start_warm into entry-reg, and the
__thead_pre_start_warm is:
        .align 3
        .global __thead_pre_start_warm
__thead_pre_start_warm:
...
        .global __reset_thead_csr_stub
__reset_thead_csr_stub:
.rept   MAX_CUSTOM_CSR
        REG_L   t2, 8(t1)
        CSR_STUB
        addi    t1, t1, 16
.endr
...

The CSR_STUB array contains all clone-csrs array. We modify it during
the early boot.

>


-- 
Best Regards
 Guo Ren


From guoren at kernel.org  Thu Jun 15 17:05:01 2023
From: guoren at kernel.org (Guo Ren)
Date: Fri, 16 Jun 2023 08:05:01 +0800
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <20230615-dice-overstuff-f1dfb456a20c@spud>
References: <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org> <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud> <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud> <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>
 <20230614-coauthor-altitude-5f5fcb23c75c@wendy> <CAJF2gTQHXrEsf=auwSU0bTesin9rXExTD3hgDpsMQPCxMYp4-A@mail.gmail.com>
 <20230615-dice-overstuff-f1dfb456a20c@spud>
Message-ID: <CAJF2gTTWZe=3q=AdjLM_5mqKWPfR=M8JDzb3GVXkxYS4adauDg@mail.gmail.com>

On Fri, Jun 16, 2023 at 12:46?AM Conor Dooley <conor at kernel.org> wrote:
>
> On Thu, Jun 15, 2023 at 11:54:38PM +0800, Guo Ren wrote:
> > On Wed, Jun 14, 2023 at 2:56?PM Conor Dooley <conor.dooley at microchip.com> wrote:
> > >
> > > On Wed, Jun 14, 2023 at 09:11:01AM +0800, Guo Ren wrote:
> > > > On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
> > > > > On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > > > > > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > > > > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > > > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > > > > > format of the reset controller:
> > >
> > > @Jisheng, iirc this was the only real outstanding thing for your Linux
> > > patchset, if you re-submit without the reset controller this week it
> > > should still be in time for v6.5.
> > I also agree let others go head first, thx Conor.
> >
> > >
> > > > > > > >                reset-controller at ffff019050 {
> > > > > > > >                        compatible = "thead,cpu-reset";
> > > > >
> > > > > Also, please just add the soc-specific compatibles even if the driver
> > > > > will bind against the most common form of it.
> > > > >
> > > > > > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > > > > > 0xff015004 0x0 0x0>;
> > > > > > > >                        reset-ctrl = <0x1c>;
> > > > > > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > > > > > 0x7c5 0x7cc 0x7ce>;
> > > > >
> > > > > To be honest, I don't actually understand why "clone-csrs" is even part
> > > > > of this "cpu-reset" node. It seems to serve a different purpose to
> > > > > something that could take various parts of the SoC out of reset.
> > > > > IMO, the "clone-csrs" stuff is something that should be done based on
> > > > > the soc-level compatible, and not related to the "cpu-reset" node at
> > > > > all, which (given the below) sounds more and more like a regular reset
> > > > > controller.
> > >
> > > > We need to put clone-csrs' execution entry into the reset entry (the
> > > > first reg address).
> > >
> > > So, take the first reg out too then, with the clone-csrs bits?
> > >
> > > That'd leave you with a "regular" reset controller for bits that reset
> > > various parts of the SoC & the clone-csrs stuff can be its own thing.
> > >
> > > What am I missing?
> >
> > +               tmp = (ulong)&__thead_pre_start_warm;
> > +               writel(tmp, (char *)(ulong)reg_addr + (i * 8));
> > +               tmp = (u64)(ulong)&__thead_pre_start_warm >> 32;
> > +               writel(tmp, (char *)(ulong)reg_addr + (i * 8) + 4);
> > We write __thead_pre_start_warm into entry-reg, and the
> > __thead_pre_start_warm is:
> >         .align 3
> >         .global __thead_pre_start_warm
> > __thead_pre_start_warm:
> > ...
> >         .global __reset_thead_csr_stub
> > __reset_thead_csr_stub:
> > .rept   MAX_CUSTOM_CSR
> >         REG_L   t2, 8(t1)
> >         CSR_STUB
> >         addi    t1, t1, 16
> > .endr
> > ...
> >
> > The CSR_STUB array contains all clone-csrs array. We modify it during
> > the early boot.
>
> I don't see how this answers my question. That all seems to be about
> what you originally called "entry-reg", "entry-cnt" & "csr-copy".
> That does not seem like it has almost nothing to do with what were
> originally called "control-reg" & "control-val".
>
> Per your descriptions, there appears to be a normal reset controller
> (the "control-" bits) and the CSR/hart entry point stuff crammed into
> one DT node. I am asking why you do not split what seems to be a regular
> reset controller away from the CSR/entry point stuff.
They are continuous operating processes for cold boot:

1. prepare __thead_pre_start_warm code with csr-copy
2. write __thead_pre_start_warm into entry-reg
3. write control-val bits into control-reg

Then other secondary harts would reset from __thead_pre_start_warm.

So I really don't know why I need to split them, because no other
modules would use __thead_pre_start_warm.

>
> Thanks,
> Conor.



-- 
Best Regards
 Guo Ren


From wxjstz at 126.com  Thu Jun 15 19:40:54 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 16 Jun 2023 10:40:54 +0800
Subject: [PATCH] lib: sbi: Hang when next mode not support
Message-ID: <20230616024054.739117-1-wxjstz@126.com>

The original code may let the hart that does not support next mode
enter init_warmboot. Fix this.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_init.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 423e6d8..d148bd2 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -532,10 +532,11 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
 		if (misa_extension('U'))
 			next_mode_supported = true;
 		break;
-	default:
-		sbi_hart_hang();
 	}
 
+	if (next_mode_supported == false)
+		sbi_hart_hang();
+
 	/*
 	 * Only the HART supporting privilege mode specified in the
 	 * scratch->next_mode should be allowed to become the coldboot
@@ -547,8 +548,7 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
 	 */
 
 	if (sbi_platform_cold_boot_allowed(plat, hartid)) {
-		if (next_mode_supported &&
-		    atomic_xchg(&coldboot_lottery, 1) == 0)
+		if (atomic_xchg(&coldboot_lottery, 1) == 0)
 			coldboot = true;
 	}
 
-- 
2.39.2



From anup at brainfault.org  Thu Jun 15 20:04:20 2023
From: anup at brainfault.org (Anup Patel)
Date: Fri, 16 Jun 2023 08:34:20 +0530
Subject: [PATCH] lib: sbi: Hang when next mode not support
In-Reply-To: <20230616024054.739117-1-wxjstz@126.com>
References: <20230616024054.739117-1-wxjstz@126.com>
Message-ID: <CAAhSdy1Ls1tyT3BEx+ZBYcu+7QWAxBAuUdcnjYqbhLFEr8Di=g@mail.gmail.com>

On Fri, Jun 16, 2023 at 8:11?AM Xiang W <wxjstz at 126.com> wrote:
>
> The original code may let the hart that does not support next mode
> enter init_warmboot. Fix this.
>
> Signed-off-by: Xiang W <wxjstz at 126.com>

For platforms (like SiFive Unleashed/Unmatched), we have E-core
without S-mode. The current approach allows users to run some
piece software on E-core using OpenSBI domains.

NACK to this patch because it breaks OpenSBI domains

Regards,
Anup

> ---
>  lib/sbi/sbi_init.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> index 423e6d8..d148bd2 100644
> --- a/lib/sbi/sbi_init.c
> +++ b/lib/sbi/sbi_init.c
> @@ -532,10 +532,11 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
>                 if (misa_extension('U'))
>                         next_mode_supported = true;
>                 break;
> -       default:
> -               sbi_hart_hang();
>         }
>
> +       if (next_mode_supported == false)
> +               sbi_hart_hang();
> +
>         /*
>          * Only the HART supporting privilege mode specified in the
>          * scratch->next_mode should be allowed to become the coldboot
> @@ -547,8 +548,7 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
>          */
>
>         if (sbi_platform_cold_boot_allowed(plat, hartid)) {
> -               if (next_mode_supported &&
> -                   atomic_xchg(&coldboot_lottery, 1) == 0)
> +               if (atomic_xchg(&coldboot_lottery, 1) == 0)
>                         coldboot = true;
>         }
>
> --
> 2.39.2
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From wxjstz at 126.com  Thu Jun 15 22:54:58 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 16 Jun 2023 13:54:58 +0800
Subject: [PATCH] lib: sbi: Hang when next mode not support
In-Reply-To: <CAAhSdy1Ls1tyT3BEx+ZBYcu+7QWAxBAuUdcnjYqbhLFEr8Di=g@mail.gmail.com>
References: <20230616024054.739117-1-wxjstz@126.com>
	 <CAAhSdy1Ls1tyT3BEx+ZBYcu+7QWAxBAuUdcnjYqbhLFEr8Di=g@mail.gmail.com>
Message-ID: <0072164e5f7049673831e46ea8d6076e0005a9a3.camel@126.com>

? 2023-06-16???? 08:34 +0530?Anup Patel???
> On Fri, Jun 16, 2023 at 8:11?AM Xiang W <wxjstz at 126.com> wrote:
> > 
> > The original code may let the hart that does not support next mode
> > enter init_warmboot. Fix this.
> > 
> > Signed-off-by: Xiang W <wxjstz at 126.com>
> 
> For platforms (like SiFive Unleashed/Unmatched), we have E-core
> without S-mode. The current approach allows users to run some
> piece software on E-core using OpenSBI domains.
Yes, at sbi_domain_finalize can fix the domain via fdt and
let E-core run other stuff.

Thank,
Xiang
> 
> NACK to this patch because it breaks OpenSBI domains
> 
> Regards,
> Anup
> 
> > ---
> > ?lib/sbi/sbi_init.c | 8 ++++----
> > ?1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> > index 423e6d8..d148bd2 100644
> > --- a/lib/sbi/sbi_init.c
> > +++ b/lib/sbi/sbi_init.c
> > @@ -532,10 +532,11 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
> > ??????????????? if (misa_extension('U'))
> > ??????????????????????? next_mode_supported = true;
> > ??????????????? break;
> > -?????? default:
> > -?????????????? sbi_hart_hang();
> > ??????? }
> > 
> > +?????? if (next_mode_supported == false)
> > +?????????????? sbi_hart_hang();
> > +
> > ??????? /*
> > ???????? * Only the HART supporting privilege mode specified in the
> > ???????? * scratch->next_mode should be allowed to become the coldboot
> > @@ -547,8 +548,7 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
> > ???????? */
> > 
> > ??????? if (sbi_platform_cold_boot_allowed(plat, hartid)) {
> > -?????????????? if (next_mode_supported &&
> > -?????????????????? atomic_xchg(&coldboot_lottery, 1) == 0)
> > +?????????????? if (atomic_xchg(&coldboot_lottery, 1) == 0)
> > ??????????????????????? coldboot = true;
> > ??????? }
> > 
> > --
> > 2.39.2
> > 
> > 
> > --
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi


From wxjstz at 126.com  Fri Jun 16 00:03:51 2023
From: wxjstz at 126.com (Xiang W)
Date: Fri, 16 Jun 2023 15:03:51 +0800
Subject: [PATCH] firmware: Fix find hart index
Message-ID: <20230616070351.779644-1-wxjstz@126.com>

After the loop to find the hartid is launched, assigning -1 to
index will fail in the subsequent compare instruction bge. Fix
This.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 firmware/fw_base.S | 1 -
 1 file changed, 1 deletion(-)

diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index fff09e1..b947423 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -471,7 +471,6 @@ _start_warm:
 	add	s9, s9, 4
 	add	a4, a4, 1
 	blt	a4, s7, 1b
-	li	a4, -1
 2:	add	s6, a4, zero
 3:	bge	s6, s7, _start_hang
 
-- 
2.39.2



From guoren at kernel.org  Fri Jun 16 22:26:34 2023
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 17 Jun 2023 01:26:34 -0400
Subject: [PATCH] lib: reset: Add early_init api for fdt_reset_drv
Message-ID: <20230617052634.2983006-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
text region for the secondary harts booting. After that, the
sbi_hart_pmp_configure may lock down the text region with M_READABLE &
M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
useless for the current opensbi scenario. See:

Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will
succeed; the R/W/X permissions apply only to S and U modes.

That's why current fdt_reset_thead could still work well after commit:
230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
regions"). So this patch fixes up a fake bug for the M-mode permission
setting of the future.

Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
---
 include/sbi_utils/reset/fdt_reset.h |  9 +++++----
 lib/utils/reset/fdt_reset.c         | 20 +++++++++++++-------
 lib/utils/reset/fdt_reset_thead.c   |  2 +-
 platform/generic/platform.c         |  5 ++++-
 platform/generic/sifive/fu740.c     |  2 +-
 platform/generic/starfive/jh7110.c  |  2 +-
 6 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/include/sbi_utils/reset/fdt_reset.h b/include/sbi_utils/reset/fdt_reset.h
index ea8063b8a90e..2b1849534e2b 100644
--- a/include/sbi_utils/reset/fdt_reset.h
+++ b/include/sbi_utils/reset/fdt_reset.h
@@ -15,6 +15,7 @@
 struct fdt_reset {
 	const struct fdt_match *match_table;
 	int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
+	int (*early_init)(void *fdt, int nodeoff, const struct fdt_match *match);
 };
 
 #ifdef CONFIG_FDT_RESET
@@ -22,22 +23,22 @@ struct fdt_reset {
 /**
  * fdt_reset_driver_init() - initialize reset driver based on the device-tree
  */
-int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv);
+int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early);
 
 /**
  * fdt_reset_init() - initialize reset drivers based on the device-tree
  *
  * This function shall be invoked in final init.
  */
-void fdt_reset_init(void);
+void fdt_reset_init(bool early);
 
 #else
 
-static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
+static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
 {
 	return 0;
 }
-static inline void fdt_reset_init(void) { }
+static inline void fdt_reset_init(bool early) { }
 
 #endif
 
diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c
index 4334586d39f7..a99d8ecc5907 100644
--- a/lib/utils/reset/fdt_reset.c
+++ b/lib/utils/reset/fdt_reset.c
@@ -17,31 +17,37 @@
 extern struct fdt_reset *fdt_reset_drivers[];
 extern unsigned long fdt_reset_drivers_size;
 
-int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
+int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
 {
 	int noff, rc = SBI_ENODEV;
 	const struct fdt_match *match;
+	int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
 
 	noff = fdt_find_match(fdt, -1, drv->match_table, &match);
 	if (noff < 0)
 		return SBI_ENODEV;
 
-	if (drv->init) {
-		rc = drv->init(fdt, noff, match);
+	if (early)
+		init = drv->early_init;
+	else
+		init = drv->init;
+
+	if (init) {
+		rc = init(fdt, noff, match);
 		if (rc && rc != SBI_ENODEV) {
-			sbi_printf("%s: %s init failed, %d\n",
-				   __func__, match->compatible, rc);
+			sbi_printf("%s: %s %s-init failed, %d\n",
+				   __func__, match->compatible, early?"early":"final", rc);
 		}
 	}
 
 	return rc;
 }
 
-void fdt_reset_init(void)
+void fdt_reset_init(bool early)
 {
 	int pos;
 	void *fdt = fdt_get_address();
 
 	for (pos = 0; pos < fdt_reset_drivers_size; pos++)
-		fdt_reset_driver_init(fdt, fdt_reset_drivers[pos]);
+		fdt_reset_driver_init(fdt, fdt_reset_drivers[pos], early);
 }
diff --git a/lib/utils/reset/fdt_reset_thead.c b/lib/utils/reset/fdt_reset_thead.c
index e1d6885debae..4cae037b1db7 100644
--- a/lib/utils/reset/fdt_reset_thead.c
+++ b/lib/utils/reset/fdt_reset_thead.c
@@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {
 
 struct fdt_reset fdt_reset_thead = {
 	.match_table = thead_reset_match,
-	.init = thead_reset_init
+	.early_init = thead_reset_init
 };
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index eeefef4c9533..65134e2c3895 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)
 	if (!generic_plat || !generic_plat->early_init)
 		return 0;
 
+	if (cold_boot)
+		fdt_reset_init(true);
+
 	return generic_plat->early_init(cold_boot, generic_plat_match);
 }
 
@@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)
 	int rc;
 
 	if (cold_boot)
-		fdt_reset_init();
+		fdt_reset_init(false);
 
 	if (generic_plat && generic_plat->final_init) {
 		rc = generic_plat->final_init(cold_boot, generic_plat_match);
diff --git a/platform/generic/sifive/fu740.c b/platform/generic/sifive/fu740.c
index fe71ce6a9ea5..5d3f1388beef 100644
--- a/platform/generic/sifive/fu740.c
+++ b/platform/generic/sifive/fu740.c
@@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,
 	void *fdt = fdt_get_address();
 
 	if (cold_boot) {
-		rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063);
+		rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063, false);
 		if (rc)
 			sbi_printf("%s: failed to find da9063 for reset\n",
 				   __func__);
diff --git a/platform/generic/starfive/jh7110.c b/platform/generic/starfive/jh7110.c
index dcd6306be5fc..f21fe85c6560 100644
--- a/platform/generic/starfive/jh7110.c
+++ b/platform/generic/starfive/jh7110.c
@@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,
 	void *fdt = fdt_get_address();
 
 	if (cold_boot) {
-		fdt_reset_driver_init(fdt, &fdt_reset_pmic);
+		fdt_reset_driver_init(fdt, &fdt_reset_pmic, false);
 		return starfive_jh7110_inst_init(fdt);
 	}
 
-- 
2.36.1



From apatel at ventanamicro.com  Fri Jun 16 23:43:29 2023
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 17 Jun 2023 12:13:29 +0530
Subject: [PATCH] lib: reset: Add early_init api for fdt_reset_drv
In-Reply-To: <20230617052634.2983006-1-guoren@kernel.org>
References: <20230617052634.2983006-1-guoren@kernel.org>
Message-ID: <CAK9=C2WtcENA4YYny8Q-K99MfmnBN9hDL7YghRaE56JOyzw5Xg@mail.gmail.com>

On Sat, Jun 17, 2023 at 10:57?AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
> text region for the secondary harts booting. After that, the
> sbi_hart_pmp_configure may lock down the text region with M_READABLE &
> M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
> M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
> useless for the current opensbi scenario. See:
>
> Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
> When the L bit is clear, any M-mode access matching the PMP entry will
> succeed; the R/W/X permissions apply only to S and U modes.
>
> That's why current fdt_reset_thead could still work well after commit:
> 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
> regions"). So this patch fixes up a fake bug for the M-mode permission
> setting of the future.
>
> Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
> Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
> Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> ---
>  include/sbi_utils/reset/fdt_reset.h |  9 +++++----
>  lib/utils/reset/fdt_reset.c         | 20 +++++++++++++-------
>  lib/utils/reset/fdt_reset_thead.c   |  2 +-
>  platform/generic/platform.c         |  5 ++++-
>  platform/generic/sifive/fu740.c     |  2 +-
>  platform/generic/starfive/jh7110.c  |  2 +-
>  6 files changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/include/sbi_utils/reset/fdt_reset.h b/include/sbi_utils/reset/fdt_reset.h
> index ea8063b8a90e..2b1849534e2b 100644
> --- a/include/sbi_utils/reset/fdt_reset.h
> +++ b/include/sbi_utils/reset/fdt_reset.h
> @@ -15,6 +15,7 @@
>  struct fdt_reset {
>         const struct fdt_match *match_table;
>         int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
> +       int (*early_init)(void *fdt, int nodeoff, const struct fdt_match *match);
>  };
>
>  #ifdef CONFIG_FDT_RESET
> @@ -22,22 +23,22 @@ struct fdt_reset {
>  /**
>   * fdt_reset_driver_init() - initialize reset driver based on the device-tree
>   */
> -int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv);
> +int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early);
>
>  /**
>   * fdt_reset_init() - initialize reset drivers based on the device-tree
>   *
>   * This function shall be invoked in final init.
>   */
> -void fdt_reset_init(void);
> +void fdt_reset_init(bool early);
>
>  #else
>
> -static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
> +static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
>  {
>         return 0;
>  }
> -static inline void fdt_reset_init(void) { }
> +static inline void fdt_reset_init(bool early) { }
>
>  #endif
>
> diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c
> index 4334586d39f7..a99d8ecc5907 100644
> --- a/lib/utils/reset/fdt_reset.c
> +++ b/lib/utils/reset/fdt_reset.c
> @@ -17,31 +17,37 @@
>  extern struct fdt_reset *fdt_reset_drivers[];
>  extern unsigned long fdt_reset_drivers_size;
>
> -int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
> +int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
>  {
>         int noff, rc = SBI_ENODEV;
>         const struct fdt_match *match;
> +       int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
>
>         noff = fdt_find_match(fdt, -1, drv->match_table, &match);
>         if (noff < 0)
>                 return SBI_ENODEV;
>
> -       if (drv->init) {
> -               rc = drv->init(fdt, noff, match);
> +       if (early)
> +               init = drv->early_init;
> +       else
> +               init = drv->init;
> +
> +       if (init) {
> +               rc = init(fdt, noff, match);
>                 if (rc && rc != SBI_ENODEV) {
> -                       sbi_printf("%s: %s init failed, %d\n",
> -                                  __func__, match->compatible, rc);
> +                       sbi_printf("%s: %s %s-init failed, %d\n",
> +                                  __func__, match->compatible, early?"early":"final", rc);
>                 }
>         }
>
>         return rc;
>  }
>
> -void fdt_reset_init(void)
> +void fdt_reset_init(bool early)
>  {
>         int pos;
>         void *fdt = fdt_get_address();
>
>         for (pos = 0; pos < fdt_reset_drivers_size; pos++)
> -               fdt_reset_driver_init(fdt, fdt_reset_drivers[pos]);
> +               fdt_reset_driver_init(fdt, fdt_reset_drivers[pos], early);
>  }
> diff --git a/lib/utils/reset/fdt_reset_thead.c b/lib/utils/reset/fdt_reset_thead.c
> index e1d6885debae..4cae037b1db7 100644
> --- a/lib/utils/reset/fdt_reset_thead.c
> +++ b/lib/utils/reset/fdt_reset_thead.c
> @@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {
>
>  struct fdt_reset fdt_reset_thead = {
>         .match_table = thead_reset_match,
> -       .init = thead_reset_init
> +       .early_init = thead_reset_init
>  };
> diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> index eeefef4c9533..65134e2c3895 100644
> --- a/platform/generic/platform.c
> +++ b/platform/generic/platform.c
> @@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)
>         if (!generic_plat || !generic_plat->early_init)
>                 return 0;
>
> +       if (cold_boot)
> +               fdt_reset_init(true);
> +
>         return generic_plat->early_init(cold_boot, generic_plat_match);
>  }
>
> @@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)
>         int rc;
>
>         if (cold_boot)
> -               fdt_reset_init();
> +               fdt_reset_init(false);

We don't need this "early" flag business in fdt_reset_init().

Just move the fdt_reset_init() call to generic_early_init() before
"if (!generic_plat || !generic_plat->early_init)".

Regards,
Anup

>
>         if (generic_plat && generic_plat->final_init) {
>                 rc = generic_plat->final_init(cold_boot, generic_plat_match);
> diff --git a/platform/generic/sifive/fu740.c b/platform/generic/sifive/fu740.c
> index fe71ce6a9ea5..5d3f1388beef 100644
> --- a/platform/generic/sifive/fu740.c
> +++ b/platform/generic/sifive/fu740.c
> @@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,
>         void *fdt = fdt_get_address();
>
>         if (cold_boot) {
> -               rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063);
> +               rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063, false);
>                 if (rc)
>                         sbi_printf("%s: failed to find da9063 for reset\n",
>                                    __func__);
> diff --git a/platform/generic/starfive/jh7110.c b/platform/generic/starfive/jh7110.c
> index dcd6306be5fc..f21fe85c6560 100644
> --- a/platform/generic/starfive/jh7110.c
> +++ b/platform/generic/starfive/jh7110.c
> @@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,
>         void *fdt = fdt_get_address();
>
>         if (cold_boot) {
> -               fdt_reset_driver_init(fdt, &fdt_reset_pmic);
> +               fdt_reset_driver_init(fdt, &fdt_reset_pmic, false);
>                 return starfive_jh7110_inst_init(fdt);
>         }
>
> --
> 2.36.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From guoren at kernel.org  Sun Jun 18 08:07:16 2023
From: guoren at kernel.org (guoren at kernel.org)
Date: Sun, 18 Jun 2023 11:07:16 -0400
Subject: [PATCH V2] lib: reset: Move fdt_reset_init into generic_early_init
Message-ID: <20230618150716.3317274-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
text region for the secondary harts booting. After that, the
sbi_hart_pmp_configure may lock down the text region with M_READABLE &
M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
useless for the current opensbi scenario. See:

Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will
succeed; the R/W/X permissions apply only to S and U modes.

That's why current fdt_reset_thead could still work well after commit:
230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
regions"). So this patch fixes up a fake bug for the M-mode permission
setting of the future.

Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
---
Changelog:
v2:
 - Direct move fdt_reset_init into generic_early_init
---
 platform/generic/platform.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index eeefef4c9533..bd608f6d4065 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -143,6 +143,9 @@ static int generic_nascent_init(void)
 
 static int generic_early_init(bool cold_boot)
 {
+	if (cold_boot)
+		fdt_reset_init();
+
 	if (!generic_plat || !generic_plat->early_init)
 		return 0;
 
@@ -154,9 +157,6 @@ static int generic_final_init(bool cold_boot)
 	void *fdt;
 	int rc;
 
-	if (cold_boot)
-		fdt_reset_init();
-
 	if (generic_plat && generic_plat->final_init) {
 		rc = generic_plat->final_init(cold_boot, generic_plat_match);
 		if (rc)
-- 
2.36.1



From guoren at kernel.org  Sun Jun 18 08:11:01 2023
From: guoren at kernel.org (Guo Ren)
Date: Sun, 18 Jun 2023 11:11:01 -0400
Subject: [PATCH] lib: reset: Add early_init api for fdt_reset_drv
In-Reply-To: <CAK9=C2WtcENA4YYny8Q-K99MfmnBN9hDL7YghRaE56JOyzw5Xg@mail.gmail.com>
References: <20230617052634.2983006-1-guoren@kernel.org> <CAK9=C2WtcENA4YYny8Q-K99MfmnBN9hDL7YghRaE56JOyzw5Xg@mail.gmail.com>
Message-ID: <CAJF2gTTw96wSASFyvXd09tW4zk0M0HP21DZHh_nORaON4pgm9g@mail.gmail.com>

On Sat, Jun 17, 2023 at 2:43?AM Anup Patel <apatel at ventanamicro.com> wrote:
>
> On Sat, Jun 17, 2023 at 10:57?AM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
> > text region for the secondary harts booting. After that, the
> > sbi_hart_pmp_configure may lock down the text region with M_READABLE &
> > M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
> > M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
> > useless for the current opensbi scenario. See:
> >
> > Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
> > When the L bit is clear, any M-mode access matching the PMP entry will
> > succeed; the R/W/X permissions apply only to S and U modes.
> >
> > That's why current fdt_reset_thead could still work well after commit:
> > 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
> > regions"). So this patch fixes up a fake bug for the M-mode permission
> > setting of the future.
> >
> > Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
> > Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
> > Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > ---
> >  include/sbi_utils/reset/fdt_reset.h |  9 +++++----
> >  lib/utils/reset/fdt_reset.c         | 20 +++++++++++++-------
> >  lib/utils/reset/fdt_reset_thead.c   |  2 +-
> >  platform/generic/platform.c         |  5 ++++-
> >  platform/generic/sifive/fu740.c     |  2 +-
> >  platform/generic/starfive/jh7110.c  |  2 +-
> >  6 files changed, 25 insertions(+), 15 deletions(-)
> >
> > diff --git a/include/sbi_utils/reset/fdt_reset.h b/include/sbi_utils/reset/fdt_reset.h
> > index ea8063b8a90e..2b1849534e2b 100644
> > --- a/include/sbi_utils/reset/fdt_reset.h
> > +++ b/include/sbi_utils/reset/fdt_reset.h
> > @@ -15,6 +15,7 @@
> >  struct fdt_reset {
> >         const struct fdt_match *match_table;
> >         int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
> > +       int (*early_init)(void *fdt, int nodeoff, const struct fdt_match *match);
> >  };
> >
> >  #ifdef CONFIG_FDT_RESET
> > @@ -22,22 +23,22 @@ struct fdt_reset {
> >  /**
> >   * fdt_reset_driver_init() - initialize reset driver based on the device-tree
> >   */
> > -int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv);
> > +int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early);
> >
> >  /**
> >   * fdt_reset_init() - initialize reset drivers based on the device-tree
> >   *
> >   * This function shall be invoked in final init.
> >   */
> > -void fdt_reset_init(void);
> > +void fdt_reset_init(bool early);
> >
> >  #else
> >
> > -static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
> > +static inline int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
> >  {
> >         return 0;
> >  }
> > -static inline void fdt_reset_init(void) { }
> > +static inline void fdt_reset_init(bool early) { }
> >
> >  #endif
> >
> > diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c
> > index 4334586d39f7..a99d8ecc5907 100644
> > --- a/lib/utils/reset/fdt_reset.c
> > +++ b/lib/utils/reset/fdt_reset.c
> > @@ -17,31 +17,37 @@
> >  extern struct fdt_reset *fdt_reset_drivers[];
> >  extern unsigned long fdt_reset_drivers_size;
> >
> > -int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv)
> > +int fdt_reset_driver_init(void *fdt, struct fdt_reset *drv, bool early)
> >  {
> >         int noff, rc = SBI_ENODEV;
> >         const struct fdt_match *match;
> > +       int (*init)(void *fdt, int nodeoff, const struct fdt_match *match);
> >
> >         noff = fdt_find_match(fdt, -1, drv->match_table, &match);
> >         if (noff < 0)
> >                 return SBI_ENODEV;
> >
> > -       if (drv->init) {
> > -               rc = drv->init(fdt, noff, match);
> > +       if (early)
> > +               init = drv->early_init;
> > +       else
> > +               init = drv->init;
> > +
> > +       if (init) {
> > +               rc = init(fdt, noff, match);
> >                 if (rc && rc != SBI_ENODEV) {
> > -                       sbi_printf("%s: %s init failed, %d\n",
> > -                                  __func__, match->compatible, rc);
> > +                       sbi_printf("%s: %s %s-init failed, %d\n",
> > +                                  __func__, match->compatible, early?"early":"final", rc);
> >                 }
> >         }
> >
> >         return rc;
> >  }
> >
> > -void fdt_reset_init(void)
> > +void fdt_reset_init(bool early)
> >  {
> >         int pos;
> >         void *fdt = fdt_get_address();
> >
> >         for (pos = 0; pos < fdt_reset_drivers_size; pos++)
> > -               fdt_reset_driver_init(fdt, fdt_reset_drivers[pos]);
> > +               fdt_reset_driver_init(fdt, fdt_reset_drivers[pos], early);
> >  }
> > diff --git a/lib/utils/reset/fdt_reset_thead.c b/lib/utils/reset/fdt_reset_thead.c
> > index e1d6885debae..4cae037b1db7 100644
> > --- a/lib/utils/reset/fdt_reset_thead.c
> > +++ b/lib/utils/reset/fdt_reset_thead.c
> > @@ -130,5 +130,5 @@ static const struct fdt_match thead_reset_match[] = {
> >
> >  struct fdt_reset fdt_reset_thead = {
> >         .match_table = thead_reset_match,
> > -       .init = thead_reset_init
> > +       .early_init = thead_reset_init
> >  };
> > diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> > index eeefef4c9533..65134e2c3895 100644
> > --- a/platform/generic/platform.c
> > +++ b/platform/generic/platform.c
> > @@ -146,6 +146,9 @@ static int generic_early_init(bool cold_boot)
> >         if (!generic_plat || !generic_plat->early_init)
> >                 return 0;
> >
> > +       if (cold_boot)
> > +               fdt_reset_init(true);
> > +
> >         return generic_plat->early_init(cold_boot, generic_plat_match);
> >  }
> >
> > @@ -155,7 +158,7 @@ static int generic_final_init(bool cold_boot)
> >         int rc;
> >
> >         if (cold_boot)
> > -               fdt_reset_init();
> > +               fdt_reset_init(false);
>
> We don't need this "early" flag business in fdt_reset_init().
>
> Just move the fdt_reset_init() call to generic_early_init() before
> "if (!generic_plat || !generic_plat->early_init)".
I agree and that would be more direct.
>
> Regards,
> Anup
>
> >
> >         if (generic_plat && generic_plat->final_init) {
> >                 rc = generic_plat->final_init(cold_boot, generic_plat_match);
> > diff --git a/platform/generic/sifive/fu740.c b/platform/generic/sifive/fu740.c
> > index fe71ce6a9ea5..5d3f1388beef 100644
> > --- a/platform/generic/sifive/fu740.c
> > +++ b/platform/generic/sifive/fu740.c
> > @@ -233,7 +233,7 @@ static int sifive_fu740_final_init(bool cold_boot,
> >         void *fdt = fdt_get_address();
> >
> >         if (cold_boot) {
> > -               rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063);
> > +               rc = fdt_reset_driver_init(fdt, &fdt_reset_da9063, false);
> >                 if (rc)
> >                         sbi_printf("%s: failed to find da9063 for reset\n",
> >                                    __func__);
> > diff --git a/platform/generic/starfive/jh7110.c b/platform/generic/starfive/jh7110.c
> > index dcd6306be5fc..f21fe85c6560 100644
> > --- a/platform/generic/starfive/jh7110.c
> > +++ b/platform/generic/starfive/jh7110.c
> > @@ -277,7 +277,7 @@ static int starfive_jh7110_final_init(bool cold_boot,
> >         void *fdt = fdt_get_address();
> >
> >         if (cold_boot) {
> > -               fdt_reset_driver_init(fdt, &fdt_reset_pmic);
> > +               fdt_reset_driver_init(fdt, &fdt_reset_pmic, false);
> >                 return starfive_jh7110_inst_init(fdt);
> >         }
> >
> > --
> > 2.36.1
> >
> >
> > --
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi



-- 
Best Regards
 Guo Ren


From anup at brainfault.org  Sun Jun 18 08:40:01 2023
From: anup at brainfault.org (Anup Patel)
Date: Sun, 18 Jun 2023 21:10:01 +0530
Subject: [PATCH V2] lib: reset: Move fdt_reset_init into generic_early_init
In-Reply-To: <20230618150716.3317274-1-guoren@kernel.org>
References: <20230618150716.3317274-1-guoren@kernel.org>
Message-ID: <CAAhSdy1=TKcVhUbFCyEcHE-uK3v-wYho-LAZc3=yG=MUf5ytMg@mail.gmail.com>

On Sun, Jun 18, 2023 at 8:37?PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
> text region for the secondary harts booting. After that, the
> sbi_hart_pmp_configure may lock down the text region with M_READABLE &
> M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
> M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
> useless for the current opensbi scenario. See:
>
> Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
> When the L bit is clear, any M-mode access matching the PMP entry will
> succeed; the R/W/X permissions apply only to S and U modes.
>
> That's why current fdt_reset_thead could still work well after commit:
> 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
> regions"). So this patch fixes up a fake bug for the M-mode permission
> setting of the future.
>
> Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
> Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
> Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Regards,
Anup

> ---
> Changelog:
> v2:
>  - Direct move fdt_reset_init into generic_early_init
> ---
>  platform/generic/platform.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> index eeefef4c9533..bd608f6d4065 100644
> --- a/platform/generic/platform.c
> +++ b/platform/generic/platform.c
> @@ -143,6 +143,9 @@ static int generic_nascent_init(void)
>
>  static int generic_early_init(bool cold_boot)
>  {
> +       if (cold_boot)
> +               fdt_reset_init();
> +
>         if (!generic_plat || !generic_plat->early_init)
>                 return 0;
>
> @@ -154,9 +157,6 @@ static int generic_final_init(bool cold_boot)
>         void *fdt;
>         int rc;
>
> -       if (cold_boot)
> -               fdt_reset_init();
> -
>         if (generic_plat && generic_plat->final_init) {
>                 rc = generic_plat->final_init(cold_boot, generic_plat_match);
>                 if (rc)
> --
> 2.36.1
>


From atishp at atishpatra.org  Mon Jun 19 12:55:39 2023
From: atishp at atishpatra.org (Atish Patra)
Date: Mon, 19 Jun 2023 12:55:39 -0700
Subject: CFP open for RISC-V MC at Linux Plumbers Conference 2023
Message-ID: <CAOnJCU+uMF-brnyjA1HLhupYPqL0ebOVu+ivrSn2AewuSrhtBw@mail.gmail.com>

The CFP for topic proposals for the RISC-V micro conference[1] 2023 is open now.
Please submit your proposal before it's too late!

The Linux plumbers event will be both in person and remote
(hybrid)virtual this year. More details can be found here [2].

We will start accepting proposals after 15th August 2023 to avoid last
minute visa/travel hassles.
The conference registration sells out pretty quickly too. Thus, we
would prefer to sort out the schedule sooner than later.

The final deadline is 15th October 2023 though.

[1] https://lpc.events/event/16/contributions/1148/
[2] https://lpc.events/

-- 
Regards,
Atish


From wxjstz at 126.com  Tue Jun 20 05:32:01 2023
From: wxjstz at 126.com (Xiang W)
Date: Tue, 20 Jun 2023 20:32:01 +0800
Subject: [PATCH] lib: sbi: Try to make each domain have boot hart
Message-ID: <20230620123201.1784745-1-wxjstz@126.com>

domain register will move the hart from the old domain to the
new domain, and should not move the boot hart to prevent the
old domain from losing the boot hart.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_domain.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 38a5902..46a4aef 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -543,9 +543,23 @@ int sbi_domain_register(struct sbi_domain *dom,
 			continue;
 
 		tdom = sbi_hartid_to_domain(i);
-		if (tdom)
+		if (tdom) {
+			if (i == tdom->boot_hartid) {
+				/* Newly registered domain should not
+				 * take up the boot hart of the older domain */
+				if (i == dom->boot_hartid)
+					sbi_printf("%s: failed assign Hart%d to %s, "
+						"conflict with %s\n",
+						__func__, i, dom->name, tdom->name);
+				else
+					sbi_printf("%s: skip assign Hart%d to %s, "
+						"because Hart%d is boot hart of %s\n",
+						__func__, i, dom->name, i, tdom->name);
+				continue;
+			}
 			sbi_hartmask_clear_hart(i,
 					&tdom->assigned_harts);
+		}
 		update_hartid_to_domain(i, dom);
 		sbi_hartmask_set_hart(i, &dom->assigned_harts);
 
-- 
2.39.2



From hchauhan at ventanamicro.com  Tue Jun 20 07:32:06 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:02:06 +0530
Subject: [PATCH 0/6] Add support for Smepmp
Message-ID: <20230620143212.2701598-1-hchauhan@ventanamicro.com>

This patch series adds support for the Smepmp specification.
The detection of Smepmp support in platform depends on the
ISA string present in the FDT. If "smepmp" is present in ISA
string in FDT, Smepmp is enabled.

When Smepmp is enabled, the M-mode software's free access
to S/U memory region is revoked. Hence, all the shared
memory access between M-mode and S/U-mode must be done
only after mapping the shared memory.

Himanshu Chauhan (6):
  Add macro definitions for mseccfg CSR
  Add functions to manipulate PMP entries
  Add Smepmp specific access flags for PMP entries
  Add detection of Smepmp from ISA string in FDT
  Add support for Smepmp
  Map/Unmap debug console shared memory buffers before and after
    read/write

 include/sbi/riscv_asm.h            |   6 +
 include/sbi/riscv_encoding.h       |  12 ++
 include/sbi/sbi_domain.h           |  51 +++++++-
 include/sbi/sbi_hart.h             |  20 ++++
 include/sbi_utils/fdt/fdt_helper.h |   3 +
 lib/sbi/riscv_asm.c                |  43 +++++++
 lib/sbi/sbi_domain.c               |  14 ++-
 lib/sbi/sbi_ecall_dbcn.c           |   3 +
 lib/sbi/sbi_hart.c                 | 184 ++++++++++++++++++++++++++---
 lib/sbi/sbi_init.c                 |  24 ++--
 lib/utils/fdt/fdt_helper.c         | 111 +++++++++++++++++
 platform/generic/platform.c        |   5 +
 12 files changed, 438 insertions(+), 38 deletions(-)

-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:32:07 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:02:07 +0530
Subject: [PATCH 1/6] include: sbi: Add macro definitions for mseccfg CSR
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143212.2701598-2-hchauhan@ventanamicro.com>

- Add macros for Machine Security Configuration (mseccfg) CSR
- Add macros to access/manipulate bits in msecfg CSR

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 include/sbi/riscv_encoding.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
index 4ebed97..50071ad 100644
--- a/include/sbi/riscv_encoding.h
+++ b/include/sbi/riscv_encoding.h
@@ -663,6 +663,18 @@
 #define CSR_MHPMEVENT30H		0x73e
 #define CSR_MHPMEVENT31H		0x73f
 
+/* Machine Security Configuration CSR (mseccfg) */
+#define CSR_MSECCFG_LOWER		0x747
+#define CSR_MSECCFG_UPPER		0x757
+#define CSR_MSECCFG			(CSR_MSECCFG_LOWER)
+
+#define MSECCFG_MML_SHIFT		(0)
+#define MSECCFG_MML			(_UL(1) << MSECCFG_MML_SHIFT)
+#define MSECCFG_MMWP_SHIFT		(1)
+#define MSECCFG_MMWP			(_UL(1) << MSECCFG_MMWP_SHIFT)
+#define MSECCFG_RLB_SHIFT		(2)
+#define MSECCFG_RLB			(_UL(1) << MSECCFG_RLB_SHIFT)
+
 /* Counter Overflow CSR */
 #define CSR_SCOUNTOVF			0xda0
 
-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:32:08 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:02:08 +0530
Subject: [PATCH 2/6] lib: sbi: Add functions to manipulate PMP entries
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143212.2701598-3-hchauhan@ventanamicro.com>

- Add a function to disable a given PMP entry.
- Add a function to check if a given entry is disabled.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 include/sbi/riscv_asm.h |  6 ++++++
 lib/sbi/riscv_asm.c     | 43 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index 1ff36de..2c34635 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -181,6 +181,12 @@ int misa_xlen(void);
 /* Get RISC-V ISA string representation */
 void misa_string(int xlen, char *out, unsigned int out_sz);
 
+/* Disable pmp entry at a given index */
+int pmp_disable(unsigned int n);
+
+/* Check if the matching field is set */
+int is_pmp_entry_mapped(unsigned long entry);
+
 int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
 	    unsigned long log2len);
 
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c
index cd56553..0690721 100644
--- a/lib/sbi/riscv_asm.c
+++ b/lib/sbi/riscv_asm.c
@@ -246,6 +246,49 @@ static unsigned long ctz(unsigned long x)
 	return ret;
 }
 
+int pmp_disable(unsigned int n)
+{
+	int pmpcfg_csr, pmpcfg_shift;
+	unsigned long cfgmask, pmpcfg;
+
+	if (n >= PMP_COUNT)
+		return SBI_EINVAL;
+
+#if __riscv_xlen == 32
+	pmpcfg_csr   = CSR_PMPCFG0 + (n >> 2);
+	pmpcfg_shift = (n & 3) << 3;
+#elif __riscv_xlen == 64
+	pmpcfg_csr   = (CSR_PMPCFG0 + (n >> 2)) & ~1;
+	pmpcfg_shift = (n & 7) << 3;
+#else
+# error "Unexpected __riscv_xlen"
+#endif
+
+	/* Clear the address matching bits to disable the pmp entry */
+	cfgmask = ~(0xffUL << pmpcfg_shift);
+	pmpcfg	= (csr_read_num(pmpcfg_csr) & cfgmask);
+	pmpcfg &= (~PMP_A << pmpcfg_shift);
+
+	csr_write_num(pmpcfg_csr, pmpcfg);
+
+	return SBI_OK;
+}
+
+int is_pmp_entry_mapped(unsigned long entry)
+{
+	unsigned long prot;
+	unsigned long addr;
+	unsigned long log2len;
+
+	pmp_get(entry, &prot, &addr, &log2len);
+
+	/* If address matching bits are non-zero, the entry is enable */
+	if (prot & PMP_A)
+		return true;
+
+	return false;
+}
+
 int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
 	    unsigned long log2len)
 {
-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:32:09 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:02:09 +0530
Subject: [PATCH 3/6] include: sbi: Add Smepmp specific access flags for PMP entries
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143212.2701598-4-hchauhan@ventanamicro.com>

Smepmp specification defines a truth table based on which the access is allowed to
different modes. This patch adds different flags based on this truth table.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 include/sbi/sbi_domain.h | 51 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index b05bcf4..24d3dc1 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -43,6 +43,51 @@ struct sbi_domain_memregion {
 #define SBI_DOMAIN_MEMREGION_SU_WRITABLE	(1UL << 4)
 #define SBI_DOMAIN_MEMREGION_SU_EXECUTABLE	(1UL << 5)
 
+#define SBI_DOMAIN_MEMREGION_ACCESS_MASK	(0x3fUL)
+#define SBI_DOMAIN_MEMREGION_M_ACCESS_MASK	(0x7UL)
+#define SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK	(0x38UL)
+
+#define SBI_DOMAIN_MEMREGION_SU_ACCESS_SHIFT	(3)
+
+#define SBI_DOMAIN_MEMREGION_SHARED_RDONLY	\
+					(SBI_DOMAIN_MEMREGION_M_READABLE | \
+					 SBI_DOMAIN_MEMREGION_SU_READABLE)
+
+#define SBI_DOMAIN_MEMREGION_SHARED_SUX_MRX	\
+					(SBI_DOMAIN_MEMREGION_M_READABLE   | \
+					 SBI_DOMAIN_MEMREGION_M_EXECUTABLE | \
+					 SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
+
+#define SBI_DOMAIN_MEMREGION_SHARED_SUX_MX	\
+					(SBI_DOMAIN_MEMREGION_M_EXECUTABLE | \
+					 SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
+
+#define SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW	\
+					(SBI_DOMAIN_MEMREGION_M_READABLE | \
+					 SBI_DOMAIN_MEMREGION_M_WRITABLE | \
+					 SBI_DOMAIN_MEMREGION_SU_READABLE| \
+					 SBI_DOMAIN_MEMREGION_SU_WRITABLE)
+
+#define SBI_DOMAIN_MEMREGION_SHARED_SUR_MRW	\
+					(SBI_DOMAIN_MEMREGION_M_READABLE | \
+					 SBI_DOMAIN_MEMREGION_M_WRITABLE | \
+					 SBI_DOMAIN_MEMREGION_SU_READABLE)
+
+#define SBI_DOMAIN_MEMREGION_IS_SHARED(_flags)	\
+	((_flags == SBI_DOMAIN_MEMREGION_SHARED_RDONLY)  || \
+	 (_flags == SBI_DOMAIN_MEMREGION_SHARED_SUX_MRX) || \
+	 (_flags == SBI_DOMAIN_MEMREGION_SHARED_SUX_MX)  || \
+	 (_flags == SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW)|| \
+	 (_flags == SBI_DOMAIN_MEMREGION_SHARED_SUR_MRW))
+
+#define SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(__flags) \
+	((__flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK) && \
+	 !(__flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK))
+
+#define SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(__flags) \
+	((__flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK)  && \
+	 !(__flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK))
+
 /** Bit to control if permissions are enforced on all modes */
 #define SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS	(1UL << 6)
 
@@ -78,12 +123,6 @@ struct sbi_domain_memregion {
 				(SBI_DOMAIN_MEMREGION_SU_EXECUTABLE | \
 				 SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
 
-#define SBI_DOMAIN_MEMREGION_ACCESS_MASK	(0x3fUL)
-#define SBI_DOMAIN_MEMREGION_M_ACCESS_MASK	(0x7UL)
-#define SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK	(0x38UL)
-
-#define SBI_DOMAIN_MEMREGION_SU_ACCESS_SHIFT	(3)
-
 #define SBI_DOMAIN_MEMREGION_MMIO		(1UL << 31)
 	unsigned long flags;
 };
-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:32:10 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:02:10 +0530
Subject: [PATCH 4/6] lib: sbi: Add detection of Smepmp from ISA string in FDT
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143212.2701598-5-hchauhan@ventanamicro.com>

- To enable Smepmp, the ISA string in FDT should have "smepmp" string. This patch
  adds support for parsing of Smepmp in ISA string.
- A bit is reserved for Smepmp in extensions member of sbi_hart_features
  which is set if Smepmp is detected in FDT.
- A utilty function is added to check if Smepmp is detected and enabled.
- In sbi_boot_print_hart, a print is added to display the state of Smepmp.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 include/sbi/sbi_hart.h             |   3 +
 include/sbi_utils/fdt/fdt_helper.h |   3 +
 lib/sbi/sbi_hart.c                 |   8 +++
 lib/sbi/sbi_init.c                 |   2 +
 lib/utils/fdt/fdt_helper.c         | 111 +++++++++++++++++++++++++++++
 platform/generic/platform.c        |   5 ++
 6 files changed, 132 insertions(+)

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 95b40e7..9582b52 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -36,6 +36,8 @@ enum sbi_hart_extensions {
 	SBI_HART_EXT_SMSTATEEN,
 	/** HART has Sstc extension */
 	SBI_HART_EXT_SSTC,
+	/** HART has Smepmp */
+	SBI_HART_EXT_SMEPMP,
 
 	/** Maximum index of Hart extension */
 	SBI_HART_EXT_MAX,
@@ -66,6 +68,7 @@ static inline ulong sbi_hart_expected_trap_addr(void)
 unsigned int sbi_hart_mhpm_count(struct sbi_scratch *scratch);
 void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
 			      const char *prefix, const char *suffix);
+unsigned int sbi_hart_smepmp_supported(struct sbi_scratch *scratch);
 unsigned int sbi_hart_pmp_count(struct sbi_scratch *scratch);
 unsigned long sbi_hart_pmp_granularity(struct sbi_scratch *scratch);
 unsigned int sbi_hart_pmp_addrbits(struct sbi_scratch *scratch);
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 39d7f3a..5c928ff 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -56,6 +56,9 @@ int fdt_parse_max_enabled_hart_id(void *fdt, u32 *max_hartid);
 
 int fdt_parse_timebase_frequency(void *fdt, unsigned long *freq);
 
+int fdt_parse_isa_extensions(void *fdt, unsigned int hard_id,
+			     unsigned long *extensions);
+
 int fdt_parse_gaisler_uart_node(void *fdt, int nodeoffset,
 				struct platform_uart_data *uart);
 
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 6e52cbd..c328243 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -260,6 +260,14 @@ unsigned int sbi_hart_pmp_count(struct sbi_scratch *scratch)
 	return hfeatures->pmp_count;
 }
 
+unsigned int sbi_hart_smepmp_supported(struct sbi_scratch *scratch)
+{
+	struct sbi_hart_features *hfeatures =
+		sbi_scratch_offset_ptr(scratch, hart_features_offset);
+
+	return !!(hfeatures->extensions & (_UL(1) << SBI_HART_EXT_SMEPMP));
+}
+
 unsigned long sbi_hart_pmp_granularity(struct sbi_scratch *scratch)
 {
 	struct sbi_hart_features *hfeatures =
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 423e6d8..31d2c3e 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -173,6 +173,8 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
 	misa_string(xlen, str, sizeof(str));
 	sbi_printf("Boot HART Base ISA        : %s\n", str);
 	sbi_hart_get_extensions_str(scratch, str, sizeof(str));
+	sbi_printf("SMEPMP                    : %sDetected\n",
+		   (sbi_hart_smepmp_supported(scratch) ? "" : "Not "));
 	sbi_printf("Boot HART ISA Extensions  : %s\n", str);
 	sbi_printf("Boot HART PMP Count       : %d\n",
 		   sbi_hart_pmp_count(scratch));
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index a88a4ba..db9d4c3 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -12,6 +12,7 @@
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
+#include <sbi/sbi_hart.h> /* for hart extension enums */
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/aplic.h>
 #include <sbi_utils/irqchip/imsic.h>
@@ -313,6 +314,116 @@ int fdt_parse_timebase_frequency(void *fdt, unsigned long *freq)
 	return 0;
 }
 
+static int fdt_get_isa_string(void *fdt, unsigned int hartid,
+			const char **isa_string)
+{
+	int err, cpu_offset, cpus_offset, len;
+	u32 c_hartid;
+	const fdt32_t *val;
+
+	if (!fdt)
+		return SBI_EINVAL;
+
+	cpus_offset = fdt_path_offset(fdt, "/cpus");
+	if (cpus_offset < 0)
+		return cpus_offset;
+
+	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
+		err = fdt_parse_hart_id(fdt, cpu_offset, &c_hartid);
+		if (err)
+			continue;
+
+		if (!fdt_node_is_enabled(fdt, cpu_offset))
+			continue;
+
+		if (c_hartid == hartid) {
+			val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
+			if (val && len > 0) {
+				*isa_string = (const char *)val;
+				return 0;
+			}
+		}
+	}
+
+	return SBI_EINVAL;
+}
+
+#define RISCV_ISA_EXT_NAME_LEN_MAX	32
+
+int fdt_parse_isa_extensions(void *fdt, unsigned int hartid,
+			unsigned long *extensions)
+{
+	size_t i, j, isa_len;
+	char mstr[RISCV_ISA_EXT_NAME_LEN_MAX];
+	const char *isa = NULL;
+
+	if (fdt_get_isa_string(fdt, hartid, &isa))
+		return SBI_EINVAL;
+
+	if (!isa)
+		return SBI_EINVAL;
+
+	i = 0;
+	isa_len = strlen(isa);
+
+	if (isa[i] == 'r' || isa[i] == 'R')
+		i++;
+	else
+		return SBI_EINVAL;
+
+	if (isa[i] == 'v' || isa[i] == 'V')
+		i++;
+	else
+		return SBI_EINVAL;
+
+	if (isa[i] == '3' || isa[i+1] == '2')
+		i += 2;
+	else if (isa[i] == '6' || isa[i+1] == '4')
+		i += 2;
+	else
+		return SBI_EINVAL;
+
+	/* Skip base ISA extentions */
+	for (; i < isa_len; i++) {
+		if (isa[i] == '_')
+			break;
+	}
+
+	while (i < isa_len) {
+		if (isa[i] != '_') {
+			i++;
+			continue;
+		}
+
+		/* Skip the '_' character */
+		i++;
+
+		/* Extract the multi-letter extension name */
+		j = 0;
+		while ((i < isa_len) && (isa[i] != '_') &&
+		       (j < (sizeof(mstr) - 1)))
+			mstr[j++] = isa[i++];
+		mstr[j] = '\0';
+
+		/* Skip empty multi-letter extension name */
+		if (!j)
+			continue;
+
+#define SET_ISA_EXT_MAP(name, bit)				\
+		do {						\
+			if (!strcmp(mstr, name)) {		\
+				__set_bit(bit, extensions);	\
+				continue;			\
+			}					\
+		} while (false)					\
+
+		SET_ISA_EXT_MAP("smepmp", SBI_HART_EXT_SMEPMP);
+#undef SET_ISA_EXT_MAP
+	}
+
+	return 0;
+}
+
 static int fdt_parse_uart_node_common(void *fdt, int nodeoffset,
 				      struct platform_uart_data *uart,
 				      unsigned long default_freq,
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 0c9cd95..24c0fa9 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -215,6 +215,11 @@ static int generic_extensions_init(struct sbi_hart_features *hfeatures)
 		return generic_plat->extensions_init(generic_plat_match,
 						     hfeatures);
 
+	/* Parse the ISA string from FDT and enable the listed extensions */
+	if (fdt_parse_isa_extensions(fdt_get_address(), current_hartid(),
+				     &hfeatures->extensions))
+		return 0;
+
 	return 0;
 }
 
-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:38:17 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:08:17 +0530
Subject: [PATCH 5/6] lib: sbi: Add support for Smepmp
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143817.2748474-1-hchauhan@ventanamicro.com>

- If Smepmp is enabled, the access flags of an entry are determined based on
  truth table defined in Smepmp.
- First PMP entry (index 0) is reserved.
- Existing boot PMP entries start from index 1.
- Since enabling Smepmp revokes the access privileges of the M-mode software
  on S/U-mode region, first PMP entry is used to map/unmap the shared memory
  between M and S/U-mode. This allows a temporary access window for the M-mode
  software to read/write to S/U-mode memory region.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 include/sbi/sbi_hart.h |  17 ++++
 lib/sbi/sbi_domain.c   |  14 +++-
 lib/sbi/sbi_hart.c     | 176 ++++++++++++++++++++++++++++++++++++-----
 lib/sbi/sbi_init.c     |  22 +++---
 4 files changed, 197 insertions(+), 32 deletions(-)

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 9582b52..9fb9f53 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -43,6 +43,21 @@ enum sbi_hart_extensions {
 	SBI_HART_EXT_MAX,
 };
 
+/*
+ * Smepmp enforces access boundaries between M-mode and
+ * S/U-mode. When it is enabled, the PMPs are programmed
+ * such that M-mode doesn't have access to S/U-mode memory.
+ *
+ * To give M-mode R/W access to the shared memory between M and
+ * S/U-mode, first entry is reserved. It is disabled at boot.
+ * When shared memory access is required, the physical address
+ * should be programmed into the first PMP entry with R/W
+ * permissions to the M-mode. Once the work is done, it should be
+ * unmapped. sbi_hart_map_saddr/sbi_hart_unmap_saddr function
+ * pair should be used to map/unmap the shared memory.
+ */
+#define SBI_SMEPMP_RESV_ENTRY		0
+
 struct sbi_hart_features {
 	bool detected;
 	int priv_version;
@@ -74,6 +89,8 @@ unsigned long sbi_hart_pmp_granularity(struct sbi_scratch *scratch);
 unsigned int sbi_hart_pmp_addrbits(struct sbi_scratch *scratch);
 unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch);
 int sbi_hart_pmp_configure(struct sbi_scratch *scratch);
+int sbi_hart_map_saddr(unsigned long base, unsigned long size);
+int sbi_hart_unmap_saddr(void);
 int sbi_hart_priv_version(struct sbi_scratch *scratch);
 void sbi_hart_get_priv_version_str(struct sbi_scratch *scratch,
 				   char *version_str, int nvstr);
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 38a5902..acd0f74 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -772,11 +772,17 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
 
 	root.fw_region_inited = true;
 
-	/* Root domain allow everything memory region */
+	/*
+	 * Allow SU RWX on rest of the memory region. Since pmp entries
+	 * have implicit priority on index, previous entries will
+	 * deny access to SU on M-mode region. Also, M-mode will not
+	 * have access to SU region while previous entries will allow
+	 * access to M-mode regions.
+	 */
 	sbi_domain_memregion_init(0, ~0UL,
-				  (SBI_DOMAIN_MEMREGION_READABLE |
-				   SBI_DOMAIN_MEMREGION_WRITEABLE |
-				   SBI_DOMAIN_MEMREGION_EXECUTABLE),
+				  (SBI_DOMAIN_MEMREGION_SU_READABLE |
+				   SBI_DOMAIN_MEMREGION_SU_WRITABLE |
+				   SBI_DOMAIN_MEMREGION_SU_EXECUTABLE),
 				  &root_memregs[root_memregs_count++]);
 
 	/* Root domain memory region end */
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index c328243..9678e37 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -292,11 +292,122 @@ unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch)
 	return hfeatures->mhpm_bits;
 }
 
+/*
+ * Returns Smepmp flags for a given domain and region based on permissions.
+ */
+unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch,
+				       struct sbi_domain *dom,
+				       struct sbi_domain_memregion *reg)
+{
+	unsigned int pmp_flags = 0;
+
+	if (SBI_DOMAIN_MEMREGION_IS_SHARED(reg->flags)) {
+		/* Read only for both M and SU modes */
+		if ((reg->flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK)
+		    == SBI_DOMAIN_MEMREGION_SHARED_RDONLY)
+			pmp_flags = (PMP_R | PMP_W | PMP_X);
+
+		/* Execute for SU but Read/Execute for M mode */
+		else if ((reg->flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK)
+			 == SBI_DOMAIN_MEMREGION_SHARED_SUX_MRX)
+			/* locked region */
+			pmp_flags = (PMP_L | PMP_W | PMP_X);
+
+		/* Execute only for both M and SU modes */
+		else if ((reg->flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK)
+			 == SBI_DOMAIN_MEMREGION_SHARED_SUX_MX)
+			pmp_flags = (PMP_L | PMP_W);
+
+		/* Read/Write for both M and SU modes */
+		else if ((reg->flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK)
+			 == SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW)
+			pmp_flags = (PMP_W | PMP_X);
+
+		/* Read only for SU mode but Read/Write for M mode */
+		else if ((reg->flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK)
+			 == SBI_DOMAIN_MEMREGION_SHARED_SUR_MRW)
+			pmp_flags = (PMP_W);
+	} else if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) {
+		/*
+		 * When smepmp is supported and used, M region cannot have RWX
+		 * permissions on any region.
+		 */
+		if ((reg->flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK)
+		    == SBI_DOMAIN_MEMREGION_M_RWX) {
+			sbi_printf("%s: M-mode only regions cannot have"
+				   "RWX permissions\n", __func__);
+			return 0;
+		}
+
+		/* M-mode only access regions are always locked */
+		pmp_flags |= PMP_L;
+
+		if (reg->flags & SBI_DOMAIN_MEMREGION_M_READABLE)
+			pmp_flags |= PMP_R;
+		if (reg->flags & SBI_DOMAIN_MEMREGION_M_WRITABLE)
+			pmp_flags |= PMP_W;
+		if (reg->flags & SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
+			pmp_flags |= PMP_X;
+	} else if (SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(reg->flags)) {
+		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE)
+			pmp_flags |= PMP_R;
+		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE)
+			pmp_flags |= PMP_W;
+		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
+			pmp_flags |= PMP_X;
+	}
+
+	return pmp_flags;
+}
+
+int sbi_hart_map_saddr(unsigned long addr, unsigned long size)
+{
+	/* shared R/W access for M and S/U mode */
+	unsigned int pmp_flags = (PMP_W | PMP_X);
+	unsigned long order, base = 0;
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+
+	/* If Smepmp is not supported no special mapping is required */
+	if (!sbi_hart_smepmp_supported(scratch))
+		return SBI_OK;
+
+	if (is_pmp_entry_mapped(SBI_SMEPMP_RESV_ENTRY))
+		return SBI_ENOSPC;
+
+	for (order = log2roundup(size) ; order <= __riscv_xlen; order++) {
+		if (order < __riscv_xlen) {
+			base = addr & ~((1UL << order) - 1UL);
+			if ((base <= addr) &&
+			    (addr < (base + (1UL << order))) &&
+			    (base <= (addr + size - 1UL)) &&
+			    ((addr + size - 1UL) < (base + (1UL << order))))
+				break;
+		} else {
+			return SBI_EFAIL;
+		}
+	}
+
+	pmp_set(SBI_SMEPMP_RESV_ENTRY, pmp_flags, base, order);
+
+	return SBI_OK;
+}
+
+int sbi_hart_unmap_saddr(void)
+{
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+
+	if (!sbi_hart_smepmp_supported(scratch))
+		return SBI_OK;
+
+	return pmp_disable(SBI_SMEPMP_RESV_ENTRY);
+}
+
 int sbi_hart_pmp_configure(struct sbi_scratch *scratch)
 {
 	struct sbi_domain_memregion *reg;
 	struct sbi_domain *dom = sbi_domain_thishart_ptr();
-	unsigned int pmp_idx = 0, pmp_flags, pmp_bits, pmp_gran_log2;
+	unsigned int pmp_idx = 0;
+	unsigned int pmp_flags, pmp_bits, pmp_gran_log2;
 	unsigned int pmp_count = sbi_hart_pmp_count(scratch);
 	unsigned long pmp_addr = 0, pmp_addr_max = 0;
 
@@ -307,36 +418,63 @@ int sbi_hart_pmp_configure(struct sbi_scratch *scratch)
 	pmp_bits = sbi_hart_pmp_addrbits(scratch) - 1;
 	pmp_addr_max = (1UL << pmp_bits) | ((1UL << pmp_bits) - 1);
 
+	if (sbi_hart_smepmp_supported(scratch)) {
+		/* Reserve first entry for dynamic shared mappings */
+		 pmp_idx = SBI_SMEPMP_RESV_ENTRY + 1;
+
+		/*
+		 * Set the RLB now so that, we can write to entries
+		 * even if some entries are locked.
+		 */
+		csr_write(CSR_MSECCFG, MSECCFG_RLB);
+
+		/* Disable the reserved entry */
+		pmp_disable(SBI_SMEPMP_RESV_ENTRY);
+	}
+
 	sbi_domain_for_each_memregion(dom, reg) {
 		if (pmp_count <= pmp_idx)
 			break;
 
 		pmp_flags = 0;
 
-		/*
-		 * If permissions are to be enforced for all modes on this
-		 * region, the lock bit should be set.
-		 */
-		if (reg->flags & SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS)
-			pmp_flags |= PMP_L;
-
-		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE)
-			pmp_flags |= PMP_R;
-		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE)
-			pmp_flags |= PMP_W;
-		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
-			pmp_flags |= PMP_X;
+		if (sbi_hart_smepmp_supported(scratch)) {
+			pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg);
+
+			if (pmp_flags == 0)
+				return 0;
+		} else {
+			/*
+			 * If permissions are to be enforced for all modes on
+			 * this region, the lock bit should be set.
+			 */
+			if (reg->flags & SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS)
+				pmp_flags |= PMP_L;
+
+			if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE)
+				pmp_flags |= PMP_R;
+			if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE)
+				pmp_flags |= PMP_W;
+			if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
+				pmp_flags |= PMP_X;
+		}
 
 		pmp_addr =  reg->base >> PMP_SHIFT;
-		if (pmp_gran_log2 <= reg->order && pmp_addr < pmp_addr_max)
+		if (pmp_gran_log2 <= reg->order && pmp_addr < pmp_addr_max) {
 			pmp_set(pmp_idx++, pmp_flags, reg->base, reg->order);
-		else {
-			sbi_printf("Can not configure pmp for domain %s", dom->name);
-			sbi_printf(" because memory region address %lx or size %lx is not in range\n",
-				    reg->base, reg->order);
+		} else {
+			sbi_printf("Can not configure pmp for domain %s because"
+				   " memory region address 0x%lx or size 0x%lx "
+				   "is not in range.\n", dom->name, reg->base,
+				   reg->order);
 		}
 	}
 
+	if (sbi_hart_smepmp_supported(scratch)) {
+		/* All entries are programmed. Enable MML bit. */
+		csr_write(CSR_MSECCFG, (MSECCFG_RLB | MSECCFG_MML));
+	}
+
 	/*
 	 * As per section 3.7.2 of privileged specification v1.12,
 	 * virtual address translations can be speculatively performed
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 31d2c3e..82078d9 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -358,13 +358,6 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 		sbi_hart_hang();
 	}
 
-	rc = sbi_hart_pmp_configure(scratch);
-	if (rc) {
-		sbi_printf("%s: PMP configure failed (error %d)\n",
-			   __func__, rc);
-		sbi_hart_hang();
-	}
-
 	/*
 	 * Note: Platform final initialization should be after finalizing
 	 * domains so that it sees correct domain assignment and PMP
@@ -394,6 +387,17 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 
 	sbi_boot_print_hart(scratch, hartid);
 
+	/*
+	 * Configure PMP at last because if SMEPMP is detected,
+	 * M-mode access to the S/U space will be rescinded.
+	 */
+	rc = sbi_hart_pmp_configure(scratch);
+	if (rc) {
+		sbi_printf("%s: PMP configure failed (error %d)\n",
+			   __func__, rc);
+		sbi_hart_hang();
+	}
+
 	wake_coldboot_harts(scratch, hartid);
 
 	count = sbi_scratch_offset_ptr(scratch, init_count_offset);
@@ -447,11 +451,11 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
 	if (rc)
 		sbi_hart_hang();
 
-	rc = sbi_hart_pmp_configure(scratch);
+	rc = sbi_platform_final_init(plat, false);
 	if (rc)
 		sbi_hart_hang();
 
-	rc = sbi_platform_final_init(plat, false);
+	rc = sbi_hart_pmp_configure(scratch);
 	if (rc)
 		sbi_hart_hang();
 
-- 
2.34.1



From hchauhan at ventanamicro.com  Tue Jun 20 07:38:54 2023
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 20 Jun 2023 20:08:54 +0530
Subject: [PATCH 6/6] lib: sbi: Map/Unmap debug console shared memory buffers before and after read/write
In-Reply-To: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
References: <20230620143212.2701598-1-hchauhan@ventanamicro.com>
Message-ID: <20230620143854.2752979-1-hchauhan@ventanamicro.com>

With Smepmp enabled, it is necessary for shared memory from
S/U mode to be mapped/unmapped before and after read/write
of the memory region.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
---
 lib/sbi/sbi_ecall_dbcn.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
index e0b892c..3724d70 100644
--- a/lib/sbi/sbi_ecall_dbcn.c
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -14,6 +14,7 @@
 #include <sbi/sbi_ecall_interface.h>
 #include <sbi/sbi_trap.h>
 #include <sbi/riscv_asm.h>
+#include <sbi/sbi_hart.h>
 
 static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
 				  const struct sbi_trap_regs *regs,
@@ -43,10 +44,12 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
 					regs->a1, regs->a0, smode,
 					SBI_DOMAIN_READ|SBI_DOMAIN_WRITE))
 			return SBI_ERR_INVALID_PARAM;
+		sbi_hart_map_saddr(regs->a1, regs->a0);
 		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);
+		sbi_hart_unmap_saddr();
 		return 0;
 	case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
 		sbi_putc(regs->a0);
-- 
2.34.1



From conor at kernel.org  Thu Jun 15 09:46:28 2023
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Jun 2023 17:46:28 +0100
Subject: [RFC PATCH 2/2] lib: reset: thead: Correct the naming convention
 of dts
In-Reply-To: <CAJF2gTQHXrEsf=auwSU0bTesin9rXExTD3hgDpsMQPCxMYp4-A@mail.gmail.com>
References: <CAJF2gTRgE2ceqZ7Ddi6NwT++qFGEzK-YZ4gg9mYPwTSUKiTwRw@mail.gmail.com>
 <B31C373E-7DDF-43A5-B855-DB664C940C7B@kernel.org>
 <CAJF2gTT-PkUUceDR8d3GXq4v40daJuNQ6rFHzLTAkLA_=ie=cA@mail.gmail.com>
 <CAJF2gTQNXncSUcDh0SfbRwb2GrKn7DeoQ_pgOfERXbLZ9yS_jg@mail.gmail.com>
 <20230612-graveness-uncloak-5f3634a45339@spud>
 <CAJF2gTSV-+cGj-1R6VumTqHmUt0PKJSEjrCoq5hMnBsLrg4jcw@mail.gmail.com>
 <20230613-define-constrict-7608d966e0e8@spud>
 <CAJF2gTSzD5EF0zWOzR0U2eJSR9aBzc+JjzUi04-Ce5oWgb=n9w@mail.gmail.com>
 <20230614-coauthor-altitude-5f5fcb23c75c@wendy>
 <CAJF2gTQHXrEsf=auwSU0bTesin9rXExTD3hgDpsMQPCxMYp4-A@mail.gmail.com>
Message-ID: <20230615-dice-overstuff-f1dfb456a20c@spud>

On Thu, Jun 15, 2023 at 11:54:38PM +0800, Guo Ren wrote:
> On Wed, Jun 14, 2023 at 2:56?PM Conor Dooley <conor.dooley at microchip.com> wrote:
> >
> > On Wed, Jun 14, 2023 at 09:11:01AM +0800, Guo Ren wrote:
> > > On Wed, Jun 14, 2023 at 3:36?AM Conor Dooley <conor at kernel.org> wrote:
> > > > On Tue, Jun 13, 2023 at 10:31:40AM +0800, Guo Ren wrote:
> > > > > On Mon, Jun 12, 2023 at 11:39?PM Conor Dooley <conor at kernel.org> wrote:
> > > > > > On Mon, Jun 12, 2023 at 08:57:36AM +0800, Guo Ren wrote:
> > > > > > > Jisheng Zhang would update the Linux yaml patch, here is the final dts
> > > > > > > format of the reset controller:
> >
> > @Jisheng, iirc this was the only real outstanding thing for your Linux
> > patchset, if you re-submit without the reset controller this week it
> > should still be in time for v6.5.
> I also agree let others go head first, thx Conor.
> 
> >
> > > > > > >                reset-controller at ffff019050 {
> > > > > > >                        compatible = "thead,cpu-reset";
> > > >
> > > > Also, please just add the soc-specific compatibles even if the driver
> > > > will bind against the most common form of it.
> > > >
> > > > > > >                        reg = <0xff 0xff019050 0x0 0x4>, <0xff
> > > > > > > 0xff015004 0x0 0x0>;
> > > > > > >                        reset-ctrl = <0x1c>;
> > > > > > >                        clone-csrs = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3
> > > > > > > 0x7c5 0x7cc 0x7ce>;
> > > >
> > > > To be honest, I don't actually understand why "clone-csrs" is even part
> > > > of this "cpu-reset" node. It seems to serve a different purpose to
> > > > something that could take various parts of the SoC out of reset.
> > > > IMO, the "clone-csrs" stuff is something that should be done based on
> > > > the soc-level compatible, and not related to the "cpu-reset" node at
> > > > all, which (given the below) sounds more and more like a regular reset
> > > > controller.
> >
> > > We need to put clone-csrs' execution entry into the reset entry (the
> > > first reg address).
> >
> > So, take the first reg out too then, with the clone-csrs bits?
> >
> > That'd leave you with a "regular" reset controller for bits that reset
> > various parts of the SoC & the clone-csrs stuff can be its own thing.
> >
> > What am I missing?
> 
> +               tmp = (ulong)&__thead_pre_start_warm;
> +               writel(tmp, (char *)(ulong)reg_addr + (i * 8));
> +               tmp = (u64)(ulong)&__thead_pre_start_warm >> 32;
> +               writel(tmp, (char *)(ulong)reg_addr + (i * 8) + 4);
> We write __thead_pre_start_warm into entry-reg, and the
> __thead_pre_start_warm is:
>         .align 3
>         .global __thead_pre_start_warm
> __thead_pre_start_warm:
> ...
>         .global __reset_thead_csr_stub
> __reset_thead_csr_stub:
> .rept   MAX_CUSTOM_CSR
>         REG_L   t2, 8(t1)
>         CSR_STUB
>         addi    t1, t1, 16
> .endr
> ...
> 
> The CSR_STUB array contains all clone-csrs array. We modify it during
> the early boot.

I don't see how this answers my question. That all seems to be about
what you originally called "entry-reg", "entry-cnt" & "csr-copy".
That does not seem like it has almost nothing to do with what were
originally called "control-reg" & "control-val".

Per your descriptions, there appears to be a normal reset controller
(the "control-" bits) and the CSR/hart entry point stuff crammed into
one DT node. I am asking why you do not split what seems to be a regular
reset controller away from the CSR/entry point stuff.

Thanks,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/opensbi/attachments/20230615/5c41acc6/attachment.sig>

From anup at brainfault.org  Tue Jun 20 22:48:37 2023
From: anup at brainfault.org (Anup Patel)
Date: Wed, 21 Jun 2023 11:18:37 +0530
Subject: [PATCH] firmware: Fix find hart index
In-Reply-To: <20230616070351.779644-1-wxjstz@126.com>
References: <20230616070351.779644-1-wxjstz@126.com>
Message-ID: <CAAhSdy3rzr0+Qy_rx079e0WaqF=mgrdSWbh-v9Zuoc1NaEiC+A@mail.gmail.com>

On Fri, Jun 16, 2023 at 12:34?PM Xiang W <wxjstz at 126.com> wrote:
>
> After the loop to find the hartid is launched, assigning -1 to
> index will fail in the subsequent compare instruction bge. Fix
> This.
>
> Signed-off-by: Xiang W <wxjstz at 126.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo

Thanks,
Anup

> ---
>  firmware/fw_base.S | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/firmware/fw_base.S b/firmware/fw_base.S
> index fff09e1..b947423 100644
> --- a/firmware/fw_base.S
> +++ b/firmware/fw_base.S
> @@ -471,7 +471,6 @@ _start_warm:
>         add     s9, s9, 4
>         add     a4, a4, 1
>         blt     a4, s7, 1b
> -       li      a4, -1
>  2:     add     s6, a4, zero
>  3:     bge     s6, s7, _start_hang
>
> --
> 2.39.2
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From anup at brainfault.org  Tue Jun 20 22:48:52 2023
From: anup at brainfault.org (Anup Patel)
Date: Wed, 21 Jun 2023 11:18:52 +0530
Subject: [PATCH V2] lib: reset: Move fdt_reset_init into generic_early_init
In-Reply-To: <20230618150716.3317274-1-guoren@kernel.org>
References: <20230618150716.3317274-1-guoren@kernel.org>
Message-ID: <CAAhSdy383vf-yMQYe6Dx+h0EY3cj66vvho44k28yvR8T+gXSDA@mail.gmail.com>

On Sun, Jun 18, 2023 at 8:37?PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
> text region for the secondary harts booting. After that, the
> sbi_hart_pmp_configure may lock down the text region with M_READABLE &
> M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
> M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
> useless for the current opensbi scenario. See:
>
> Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
> When the L bit is clear, any M-mode access matching the PMP entry will
> succeed; the R/W/X permissions apply only to S and U modes.
>
> That's why current fdt_reset_thead could still work well after commit:
> 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW
> regions"). So this patch fixes up a fake bug for the M-mode permission
> setting of the future.
>
> Fixes: 230278dcf127 ("lib: sbi: Add separate entries for firmware RX and RW regions")
> Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
> Reported-by: Jessica Clarke <jrtc27 at jrtc27.com>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>

Applied this patch to the riscv/opensbi repo

Thanks,
Anup

> ---
> Changelog:
> v2:
>  - Direct move fdt_reset_init into generic_early_init
> ---
>  platform/generic/platform.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> index eeefef4c9533..bd608f6d4065 100644
> --- a/platform/generic/platform.c
> +++ b/platform/generic/platform.c
> @@ -143,6 +143,9 @@ static int generic_nascent_init(void)
>
>  static int generic_early_init(bool cold_boot)
>  {
> +       if (cold_boot)
> +               fdt_reset_init();
> +
>         if (!generic_plat || !generic_plat->early_init)
>                 return 0;
>
> @@ -154,9 +157,6 @@ static int generic_final_init(bool cold_boot)
>         void *fdt;
>         int rc;
>
> -       if (cold_boot)
> -               fdt_reset_init();
> -
>         if (generic_plat && generic_plat->final_init) {
>                 rc = generic_plat->final_init(cold_boot, generic_plat_match);
>                 if (rc)
> --
> 2.36.1
>


From gianluca at rivosinc.com  Thu Jun 22 10:38:59 2023
From: gianluca at rivosinc.com (Gianluca Guida)
Date: Thu, 22 Jun 2023 18:38:59 +0100
Subject: [PATCH] lib: sbi: check A2 register in ecall_dbcn_handler.
Message-ID: <20230622173857.387914-1-gianluca@rivosinc.com>

Do not ignore register A2 (high bits of physical address) in the dbcn
handler (RV64).

Signed-off-by: Gianluca Guida <gianluca at rivosinc.com>
---

The spec doesn't seem to imply that in RV64 only one paramenter will
be used.

Thanks,
G.


 lib/sbi/sbi_ecall_dbcn.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
index e0b892c..ecec027 100644
--- a/lib/sbi/sbi_ecall_dbcn.c
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -34,11 +34,14 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
 		 * Based on above, we simply fail if the upper 32bits of
 		 * the physical address (i.e. a2 register) is non-zero on
 		 * RV32.
+                 *
+                 * Analogously, we fail if the upper 64bit of the
+                 * physical address (i.e. a2 register) is non-zero on
+                 * RV64.
 		 */
-#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))
-- 
2.34.1



From anup at brainfault.org  Thu Jun 22 23:42:46 2023
From: anup at brainfault.org (Anup Patel)
Date: Fri, 23 Jun 2023 12:12:46 +0530
Subject: [PATCH] lib: sbi: check A2 register in ecall_dbcn_handler.
In-Reply-To: <20230622173857.387914-1-gianluca@rivosinc.com>
References: <20230622173857.387914-1-gianluca@rivosinc.com>
Message-ID: <CAAhSdy35=rQp-PbVv=0hTQbHEnBqQ2ben03DbXqt23u3H3hHnA@mail.gmail.com>

On Thu, Jun 22, 2023 at 11:10?PM Gianluca Guida <gianluca at rivosinc.com> wrote:
>
> Do not ignore register A2 (high bits of physical address) in the dbcn
> handler (RV64).
>
> Signed-off-by: Gianluca Guida <gianluca at rivosinc.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>
> The spec doesn't seem to imply that in RV64 only one paramenter will
> be used.
>
> Thanks,
> G.
>
>
>  lib/sbi/sbi_ecall_dbcn.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
> index e0b892c..ecec027 100644
> --- a/lib/sbi/sbi_ecall_dbcn.c
> +++ b/lib/sbi/sbi_ecall_dbcn.c
> @@ -34,11 +34,14 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
>                  * Based on above, we simply fail if the upper 32bits of
>                  * the physical address (i.e. a2 register) is non-zero on
>                  * RV32.
> +                 *
> +                 * Analogously, we fail if the upper 64bit of the
> +                 * physical address (i.e. a2 register) is non-zero on
> +                 * RV64.
>                  */
> -#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))
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From anup at brainfault.org  Fri Jun 23 00:48:53 2023
From: anup at brainfault.org (Anup Patel)
Date: Fri, 23 Jun 2023 13:18:53 +0530
Subject: OpenSBI v1.3 Released
Message-ID: <CAAhSdy0S7UWzroJV04w4xfQvcaXoQ_a7zXfT9aLaYT5kWWPJ=Q@mail.gmail.com>

Hi All,

The OpenSBI v1.3 is now available on GitHub at:
https://github.com/riscv-software-src/opensbi/releases

This release has:

* Allow platform to influence cold boot HART selection
* Starfive JH7110 platform support
* Split RX and RW firmware regions
* Advertise nonretentive suspend for allwinner D1 platform
* Byteorder/endianness conversion macros
* SBI debug console extension (Experimental)
* Configure the PMA regions for RZ/Five platform
* SBI system suspend extension (Experimental)
* SBI PMU platform firmware events (Experimental)
* SBI CPPC extension (Experimental)
* Optimized remote TLB flushes
* Simple heap for boot time memory allocations
* Bring back no-map DT property for reserved memory nodes

Overall, this release mainly adds new SBI extensions along
with other improvements.

Many thanks to everyone who has contributed to this release.

Best Regards,
Anup Patel


From ajones at ventanamicro.com  Sat Jun 24 04:08:48 2023
From: ajones at ventanamicro.com (Andrew Jones)
Date: Sat, 24 Jun 2023 13:08:48 +0200
Subject: [PATCH] lib: sbi: check A2 register in ecall_dbcn_handler.
In-Reply-To: <20230622173857.387914-1-gianluca@rivosinc.com>
References: <20230622173857.387914-1-gianluca@rivosinc.com>
Message-ID: <20230624-7cb81b92e2a280b55e61b675@orel>

On Thu, Jun 22, 2023 at 06:38:59PM +0100, Gianluca Guida wrote:
> Do not ignore register A2 (high bits of physical address) in the dbcn
> handler (RV64).
> 
> Signed-off-by: Gianluca Guida <gianluca at rivosinc.com>
> ---
> 
> The spec doesn't seem to imply that in RV64 only one paramenter will
> be used.
> 
> Thanks,
> G.
> 
> 
>  lib/sbi/sbi_ecall_dbcn.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
> index e0b892c..ecec027 100644
> --- a/lib/sbi/sbi_ecall_dbcn.c
> +++ b/lib/sbi/sbi_ecall_dbcn.c
> @@ -34,11 +34,14 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
>  		 * Based on above, we simply fail if the upper 32bits of
>  		 * the physical address (i.e. a2 register) is non-zero on
>  		 * RV32.
> +                 *
> +                 * Analogously, we fail if the upper 64bit of the
> +                 * physical address (i.e. a2 register) is non-zero on
> +                 * RV64.

I see I'm too late, since Anup already applied, but the above lines have
leading spaces instead of tabs.

Thanks,
drew

>  		 */
> -#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))
> -- 
> 2.34.1
> 
> 
> -- 
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


From dfustini at baylibre.com  Mon Jun 26 21:12:45 2023
From: dfustini at baylibre.com (Drew Fustini)
Date: Mon, 26 Jun 2023 21:12:45 -0700
Subject: CFP open for RISC-V MC at Linux Plumbers Conference 2023
In-Reply-To: <CAOnJCU+uMF-brnyjA1HLhupYPqL0ebOVu+ivrSn2AewuSrhtBw@mail.gmail.com>
References: <CAOnJCU+uMF-brnyjA1HLhupYPqL0ebOVu+ivrSn2AewuSrhtBw@mail.gmail.com>
Message-ID: <ZJphvbTsp6Q4Dfrq@x1>

On Mon, Jun 19, 2023 at 12:55:39PM -0700, Atish Patra wrote:
> The CFP for topic proposals for the RISC-V micro conference[1] 2023 is open now.
> Please submit your proposal before it's too late!

Thanks for posting. I am looking forward to it!

> The Linux plumbers event will be both in person and remote
> (hybrid)virtual this year. More details can be found here [2].
> 
> We will start accepting proposals after 15th August 2023 to avoid last
> minute visa/travel hassles.
> The conference registration sells out pretty quickly too. Thus, we
> would prefer to sort out the schedule sooner than later.
> 
> The final deadline is 15th October 2023 though.
> 
> [1] https://lpc.events/event/16/contributions/1148/

I think that page is from 2022 and that this would be a better link:
https://lpc.events/blog/current/index.php/2023/06/23/risc-v-microconference-cfp/

Drew


From atishp at atishpatra.org  Mon Jun 26 23:21:12 2023
From: atishp at atishpatra.org (Atish Patra)
Date: Mon, 26 Jun 2023 23:21:12 -0700
Subject: CFP open for RISC-V MC at Linux Plumbers Conference 2023
In-Reply-To: <ZJphvbTsp6Q4Dfrq@x1>
References: <CAOnJCU+uMF-brnyjA1HLhupYPqL0ebOVu+ivrSn2AewuSrhtBw@mail.gmail.com>
 <ZJphvbTsp6Q4Dfrq@x1>
Message-ID: <CAOnJCU+HqEgGpLGb1-4JrSC30rZZ_8Z5h3HMAKUN2xFu-D8uvA@mail.gmail.com>

On Mon, Jun 26, 2023 at 9:08?PM Drew Fustini <dfustini at baylibre.com> wrote:
>
> On Mon, Jun 19, 2023 at 12:55:39PM -0700, Atish Patra wrote:
> > The CFP for topic proposals for the RISC-V micro conference[1] 2023 is open now.
> > Please submit your proposal before it's too late!
>
> Thanks for posting. I am looking forward to it!
>
> > The Linux plumbers event will be both in person and remote
> > (hybrid)virtual this year. More details can be found here [2].
> >
> > We will start accepting proposals after 15th August 2023 to avoid last
> > minute visa/travel hassles.
> > The conference registration sells out pretty quickly too. Thus, we
> > would prefer to sort out the schedule sooner than later.
> >
> > The final deadline is 15th October 2023 though.
> >
> > [1] https://lpc.events/event/16/contributions/1148/
>
> I think that page is from 2022 and that this would be a better link:

Copy paste error :(

> https://lpc.events/blog/current/index.php/2023/06/23/risc-v-microconference-cfp/
>

Thanks.

> Drew



-- 
Regards,
Atish


From gianluca at rivosinc.com  Thu Jun 29 07:18:45 2023
From: gianluca at rivosinc.com (Gianluca Guida)
Date: Thu, 29 Jun 2023 15:18:45 +0100
Subject: [PATCH] lib: sbi: check A2 register in ecall_dbcn_handler.
In-Reply-To: <20230624-7cb81b92e2a280b55e61b675@orel>
References: <20230622173857.387914-1-gianluca@rivosinc.com> <20230624-7cb81b92e2a280b55e61b675@orel>
Message-ID: <CAOOZEBQvm56i2qzxvmVR0JPgPtOghwrjN0JV=z-cY5oa2QMr8g@mail.gmail.com>

On Sat, Jun 24, 2023 at 12:08?PM Andrew Jones <ajones at ventanamicro.com> wrote:
[...]
> >  lib/sbi/sbi_ecall_dbcn.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
> > index e0b892c..ecec027 100644
> > --- a/lib/sbi/sbi_ecall_dbcn.c
> > +++ b/lib/sbi/sbi_ecall_dbcn.c
> > @@ -34,11 +34,14 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
> >                * Based on above, we simply fail if the upper 32bits of
> >                * the physical address (i.e. a2 register) is non-zero on
> >                * RV32.
> > +                 *
> > +                 * Analogously, we fail if the upper 64bit of the
> > +                 * physical address (i.e. a2 register) is non-zero on
> > +                 * RV64.
>
> I see I'm too late, since Anup already applied, but the above lines have
> leading spaces instead of tabs.
>

I'll send a follow-up patch.

Thank you,
G.


From gianluca at rivosinc.com  Thu Jun 29 07:24:08 2023
From: gianluca at rivosinc.com (Gianluca Guida)
Date: Thu, 29 Jun 2023 15:24:08 +0100
Subject: [PATCH] lib: sbi: fix comment indent
Message-ID: <20230629142406.6796-1-gianluca@rivosinc.com>

Use tabs rather than spaces.

Signed-off-by: Gianluca Guida <gianluca at rivosinc.com>
---
 lib/sbi/sbi_ecall_dbcn.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/sbi/sbi_ecall_dbcn.c b/lib/sbi/sbi_ecall_dbcn.c
index ecec027..8e68729 100644
--- a/lib/sbi/sbi_ecall_dbcn.c
+++ b/lib/sbi/sbi_ecall_dbcn.c
@@ -34,10 +34,10 @@ static int sbi_ecall_dbcn_handler(unsigned long extid, unsigned long funcid,
 		 * Based on above, we simply fail if the upper 32bits of
 		 * the physical address (i.e. a2 register) is non-zero on
 		 * RV32.
-                 *
-                 * Analogously, we fail if the upper 64bit of the
-                 * physical address (i.e. a2 register) is non-zero on
-                 * RV64.
+		 *
+		 * Analogously, we fail if the upper 64bit of the
+		 * physical address (i.e. a2 register) is non-zero on
+		 * RV64.
 		 */
 		if (regs->a2)
 			return SBI_ERR_FAILED;
-- 
2.34.1



