diff mbox series

[v2,7/8] lib: sbi: Add functions to map/unmap shared memory

Message ID 20230706104928.3391947-8-hchauhan@ventanamicro.com
State Superseded
Headers show
Series Add support for Smepmp | expand

Commit Message

Himanshu Chauhan July 6, 2023, 10:49 a.m. UTC
When Smepmp is enabled, M-mode will need to map/unmap the
shared memory before it can read/write to it. This patch
adds functions to create dynamic short-lived mappings.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
---
 include/sbi/sbi_hart.h |  2 ++
 lib/sbi/sbi_hart.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

Comments

Anup Patel July 6, 2023, 12:01 p.m. UTC | #1
On Thu, Jul 6, 2023 at 4:19 PM Himanshu Chauhan
<hchauhan@ventanamicro.com> wrote:
>
> When Smepmp is enabled, M-mode will need to map/unmap the
> shared memory before it can read/write to it. This patch
> adds functions to create dynamic short-lived mappings.
>
> Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>

Looks good to me.

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

Regards,
Anup

> ---
>  include/sbi/sbi_hart.h |  2 ++
>  lib/sbi/sbi_hart.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
>
> diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
> index fb5bb59..975966d 100644
> --- a/include/sbi/sbi_hart.h
> +++ b/include/sbi/sbi_hart.h
> @@ -88,6 +88,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_hart.c b/lib/sbi/sbi_hart.c
> index 5d91718..936dbda 100644
> --- a/lib/sbi/sbi_hart.c
> +++ b/lib/sbi/sbi_hart.c
> @@ -347,6 +347,48 @@ unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch,
>         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_has_extension(scratch, SBI_HART_EXT_SMEPMP))
> +               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_has_extension(scratch, SBI_HART_EXT_SMEPMP))
> +               return SBI_OK;
> +
> +       return pmp_disable(SBI_SMEPMP_RESV_ENTRY);
> +}
> +
>  int sbi_hart_pmp_configure(struct sbi_scratch *scratch)
>  {
>         struct sbi_domain_memregion *reg;
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
diff mbox series

Patch

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index fb5bb59..975966d 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -88,6 +88,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_hart.c b/lib/sbi/sbi_hart.c
index 5d91718..936dbda 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -347,6 +347,48 @@  unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch,
 	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_has_extension(scratch, SBI_HART_EXT_SMEPMP))
+		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_has_extension(scratch, SBI_HART_EXT_SMEPMP))
+		return SBI_OK;
+
+	return pmp_disable(SBI_SMEPMP_RESV_ENTRY);
+}
+
 int sbi_hart_pmp_configure(struct sbi_scratch *scratch)
 {
 	struct sbi_domain_memregion *reg;