diff mbox series

[v6,3/6] riscv: Provide a mechanism to fix DT for reserved memory

Message ID 20200418193228.44209-4-atish.patra@wdc.com
State Superseded
Headers show
Series RISC-V DT related fixes for reserved memory & UEFI | expand

Commit Message

Atish Patra April 18, 2020, 7:32 p.m. UTC
In RISC-V, M-mode software can reserve physical memory regions
by setting appropriate physical memory protection (PMP) csr. As the
PMP csr are accessible only in M-mode, S-mode U-Boot can not read
this configuration directly. However, M-mode software can pass this
information via reserved-memory node in device tree so that S-mode
software can access this information.

This patch provides a framework to copy to the reserved-memory node
from one DT to another. This will be used to update the DT used by
U-Boot and the DT passed to the next stage OS.

Signed-off-by: Atish Patra <atish.patra at wdc.com>
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
---
 arch/riscv/cpu/start.S                |   1 +
 arch/riscv/include/asm/global_data.h  |   1 +
 arch/riscv/include/asm/u-boot-riscv.h |   2 +
 arch/riscv/lib/Makefile               |   1 +
 arch/riscv/lib/asm-offsets.c          |   1 +
 arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
 6 files changed, 108 insertions(+)
 create mode 100644 arch/riscv/lib/fdt_fixup.c

Comments

Bin Meng April 20, 2020, 5:29 a.m. UTC | #1
On Sun, Apr 19, 2020 at 3:32 AM Atish Patra <atish.patra at wdc.com> wrote:
>
> In RISC-V, M-mode software can reserve physical memory regions
> by setting appropriate physical memory protection (PMP) csr. As the
> PMP csr are accessible only in M-mode, S-mode U-Boot can not read
> this configuration directly. However, M-mode software can pass this
> information via reserved-memory node in device tree so that S-mode
> software can access this information.
>
> This patch provides a framework to copy to the reserved-memory node
> from one DT to another. This will be used to update the DT used by
> U-Boot and the DT passed to the next stage OS.
>
> Signed-off-by: Atish Patra <atish.patra at wdc.com>
> Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> ---
>  arch/riscv/cpu/start.S                |   1 +
>  arch/riscv/include/asm/global_data.h  |   1 +
>  arch/riscv/include/asm/u-boot-riscv.h |   2 +
>  arch/riscv/lib/Makefile               |   1 +
>  arch/riscv/lib/asm-offsets.c          |   1 +
>  arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
>  6 files changed, 108 insertions(+)
>  create mode 100644 arch/riscv/lib/fdt_fixup.c
>

Tested-by: Bin Meng <bmeng.cn at gmail.com>
Rick Chen April 20, 2020, 8:40 a.m. UTC | #2
Hi Atish

> From: Atish Patra [mailto:atish.patra at wdc.com]
> Sent: Sunday, April 19, 2020 3:32 AM
> To: u-boot at lists.denx.de
> Cc: Atish Patra; Bin Meng; Anup Patel; Lukas Auer; Heinrich Schuchardt; agraf at csgraf.de; ard.biesheuvel at linaro.org; Marcus Comstedt; Paul Walmsley; Rick Jian-Zhi Chen(???); palmer at dabbelt.com
> Subject: [PATCH v6 3/6] riscv: Provide a mechanism to fix DT for reserved memory
>
> In RISC-V, M-mode software can reserve physical memory regions by setting appropriate physical memory protection (PMP) csr. As the PMP csr are accessible only in M-mode, S-mode U-Boot can not read this configuration directly. However, M-mode software can pass this information via reserved-memory node in device tree so that S-mode software can access this information.
>
> This patch provides a framework to copy to the reserved-memory node from one DT to another. This will be used to update the DT used by U-Boot and the DT passed to the next stage OS.
>
> Signed-off-by: Atish Patra <atish.patra at wdc.com>
> Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> ---
>  arch/riscv/cpu/start.S                |   1 +
>  arch/riscv/include/asm/global_data.h  |   1 +
>  arch/riscv/include/asm/u-boot-riscv.h |   2 +
>  arch/riscv/lib/Makefile               |   1 +
>  arch/riscv/lib/asm-offsets.c          |   1 +
>  arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
>  6 files changed, 108 insertions(+)
>  create mode 100644 arch/riscv/lib/fdt_fixup.c
>

I am trying to applied Bin and your patch.
The sequence of apply is according to submit date.
This patch seem conflict with [PATCH v2 2/6] riscv: Merge unnecessary
SMP ifdefs in start.S of Bin
Can you rebase it and send again ?

Thanks
Rick

> diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 6b3ff99c3882..0282685c2906 100644
> --- a/arch/riscv/cpu/start.S
> +++ b/arch/riscv/cpu/start.S
> @@ -121,6 +121,7 @@ call_board_init_f_0:
>
>         jal     board_init_f_init_reserve
>
> +       SREG    s1, GD_FIRMWARE_FDT_ADDR(gp)
>         /* save the boot hart id to global_data */
>         SREG    tp, GD_BOOT_HART(gp)
>
> diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> index b74bd7e738bb..51ac8d1c98e2 100644
> --- a/arch/riscv/include/asm/global_data.h
> +++ b/arch/riscv/include/asm/global_data.h
> @@ -15,6 +15,7 @@
>  /* Architecture-specific global data */  struct arch_global_data {
>         long boot_hart;         /* boot hart id */
> +       phys_addr_t firmware_fdt_addr;
>  #ifdef CONFIG_SIFIVE_CLINT
>         void __iomem *clint;    /* clint base address */
>  #endif
> diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
> index 49febd588102..543a1688db8f 100644
> --- a/arch/riscv/include/asm/u-boot-riscv.h
> +++ b/arch/riscv/include/asm/u-boot-riscv.h
> @@ -17,5 +17,7 @@ int cleanup_before_linux(void);
>  /* board/.../... */
>  int board_init(void);
>  void board_quiesce_devices(void);
> +int riscv_board_reserved_mem_fixup(void *fdt); int
> +riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
>
>  #endif /* _U_BOOT_RISCV_H_ */
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index adadbf4bcbef..d132b59ce32c 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -24,6 +24,7 @@ obj-y += reset.o
>  obj-y   += setjmp.o
>  obj-$(CONFIG_SMP) += smp.o
>  obj-$(CONFIG_SPL_BUILD)        += spl.o
> +obj-y   += fdt_fixup.o
>
>  # For building EFI apps
>  CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
> diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 4fa4fd371473..7301c1b98e23 100644
> --- a/arch/riscv/lib/asm-offsets.c
> +++ b/arch/riscv/lib/asm-offsets.c
> @@ -14,6 +14,7 @@
>  int main(void)
>  {
>         DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
> +       DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
>  #ifndef CONFIG_XIP
>         DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));  #endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c new file mode 100644 index 000000000000..1fce41490973
> --- /dev/null
> +++ b/arch/riscv/lib/fdt_fixup.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2020 Western Digital Corporation or its affiliates
> + *
> + */
> +
> +#include <common.h>
> +#include <fdt_support.h>
> +#include <mapmem.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/**
> + * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
> + * @src: Pointer to the source device tree from which reserved memory node
> + *      needs to be copied.
> + * @dst: Pointer to the destination device tree to which reserved memory node
> + *      needs to be copied.
> + *
> + * Return: 0 on success or if source doesn't have reserved memory node.
> + *        Error if copy process failed.
> + */
> +int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) {
> +       u32 phandle;
> +       struct fdt_memory pmp_mem;
> +       fdt_addr_t addr;
> +       fdt_size_t size;
> +       int offset, node, err, rmem_offset;
> +       bool nomap = true;
> +       char basename[32] = {0};
> +       int bname_len;
> +       int max_len = sizeof(basename);
> +       const char *name;
> +       char *temp;
> +
> +       offset = fdt_path_offset(src, "/reserved-memory");
> +       if (offset < 0) {
> +               printf("No reserved memory region found in source FDT\n");
> +               return 0;
> +       }
> +
> +       fdt_for_each_subnode(node, src, offset) {
> +               name = fdt_get_name(src, node, NULL);
> +
> +               addr = fdtdec_get_addr_size_auto_noparent(src, node,
> +                                                         "reg", 0, &size,
> +                                                         false);
> +               if (addr == FDT_ADDR_T_NONE) {
> +                       debug("failed to read address/size for %s\n", name);
> +                       continue;
> +               }
> +               strncpy(basename, name, max_len);
> +               temp = strchr(basename, '@');
> +               if (temp) {
> +                       bname_len = strnlen(basename, max_len) - strnlen(temp,
> +                                                                      max_len);
> +                       *(basename + bname_len) = '\0';
> +               }
> +               pmp_mem.start = addr;
> +               pmp_mem.end = addr + size - 1;
> +               err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
> +                                                &phandle);
> +               if (err < 0) {
> +                       printf("failed to add reserved memory: %d\n", err);
> +                       return err;
> +               }
> +               if (!fdt_getprop(src, node, "no-map", NULL))
> +                       nomap = false;
> +               if (nomap) {
> +                       rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
> +                       fdt_setprop_empty(dst, rmem_offset, "no-map");
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a
> +board
> + * @fdt: Pointer to the device tree in which reserved memory node needs to be
> + *      added.
> + *
> + * In RISC-V, any board compiled with OF_SEPARATE needs to copy the
> +reserved
> + * memory node from the device tree provided by the firmware to the
> +device tree
> + * used by U-Boot. This is a common function that individual board
> +fixup
> + * functions can invoke.
> + *
> + * Return: 0 on success or error otherwise.
> + */
> +int riscv_board_reserved_mem_fixup(void *fdt) {
> +       int err;
> +       void *src_fdt_addr;
> +
> +       src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
> +       err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
> +       if (err < 0)
> +               return err;
> +
> +       return 0;
> +}
> --
> 2.25.1
>
> CONFIDENTIALITY NOTICE:
>
> This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.
>
> Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.
Atish Patra April 21, 2020, 3:34 a.m. UTC | #3
On Mon, Apr 20, 2020 at 1:41 AM Rick Chen <rickchen36 at gmail.com> wrote:
>
> Hi Atish
>
> > From: Atish Patra [mailto:atish.patra at wdc.com]
> > Sent: Sunday, April 19, 2020 3:32 AM
> > To: u-boot at lists.denx.de
> > Cc: Atish Patra; Bin Meng; Anup Patel; Lukas Auer; Heinrich Schuchardt; agraf at csgraf.de; ard.biesheuvel at linaro.org; Marcus Comstedt; Paul Walmsley; Rick Jian-Zhi Chen(???); palmer at dabbelt.com
> > Subject: [PATCH v6 3/6] riscv: Provide a mechanism to fix DT for reserved memory
> >
> > In RISC-V, M-mode software can reserve physical memory regions by setting appropriate physical memory protection (PMP) csr. As the PMP csr are accessible only in M-mode, S-mode U-Boot can not read this configuration directly. However, M-mode software can pass this information via reserved-memory node in device tree so that S-mode software can access this information.
> >
> > This patch provides a framework to copy to the reserved-memory node from one DT to another. This will be used to update the DT used by U-Boot and the DT passed to the next stage OS.
> >
> > Signed-off-by: Atish Patra <atish.patra at wdc.com>
> > Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> > ---
> >  arch/riscv/cpu/start.S                |   1 +
> >  arch/riscv/include/asm/global_data.h  |   1 +
> >  arch/riscv/include/asm/u-boot-riscv.h |   2 +
> >  arch/riscv/lib/Makefile               |   1 +
> >  arch/riscv/lib/asm-offsets.c          |   1 +
> >  arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
> >  6 files changed, 108 insertions(+)
> >  create mode 100644 arch/riscv/lib/fdt_fixup.c
> >
>
> I am trying to applied Bin and your patch.
> The sequence of apply is according to submit date.
> This patch seem conflict with [PATCH v2 2/6] riscv: Merge unnecessary
> SMP ifdefs in start.S of Bin
> Can you rebase it and send again ?
>

Ok. I will rebase on top of Bin's series and resend.

> Thanks
> Rick
>
> > diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 6b3ff99c3882..0282685c2906 100644
> > --- a/arch/riscv/cpu/start.S
> > +++ b/arch/riscv/cpu/start.S
> > @@ -121,6 +121,7 @@ call_board_init_f_0:
> >
> >         jal     board_init_f_init_reserve
> >
> > +       SREG    s1, GD_FIRMWARE_FDT_ADDR(gp)
> >         /* save the boot hart id to global_data */
> >         SREG    tp, GD_BOOT_HART(gp)
> >
> > diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> > index b74bd7e738bb..51ac8d1c98e2 100644
> > --- a/arch/riscv/include/asm/global_data.h
> > +++ b/arch/riscv/include/asm/global_data.h
> > @@ -15,6 +15,7 @@
> >  /* Architecture-specific global data */  struct arch_global_data {
> >         long boot_hart;         /* boot hart id */
> > +       phys_addr_t firmware_fdt_addr;
> >  #ifdef CONFIG_SIFIVE_CLINT
> >         void __iomem *clint;    /* clint base address */
> >  #endif
> > diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
> > index 49febd588102..543a1688db8f 100644
> > --- a/arch/riscv/include/asm/u-boot-riscv.h
> > +++ b/arch/riscv/include/asm/u-boot-riscv.h
> > @@ -17,5 +17,7 @@ int cleanup_before_linux(void);
> >  /* board/.../... */
> >  int board_init(void);
> >  void board_quiesce_devices(void);
> > +int riscv_board_reserved_mem_fixup(void *fdt); int
> > +riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
> >
> >  #endif /* _U_BOOT_RISCV_H_ */
> > diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index adadbf4bcbef..d132b59ce32c 100644
> > --- a/arch/riscv/lib/Makefile
> > +++ b/arch/riscv/lib/Makefile
> > @@ -24,6 +24,7 @@ obj-y += reset.o
> >  obj-y   += setjmp.o
> >  obj-$(CONFIG_SMP) += smp.o
> >  obj-$(CONFIG_SPL_BUILD)        += spl.o
> > +obj-y   += fdt_fixup.o
> >
> >  # For building EFI apps
> >  CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
> > diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 4fa4fd371473..7301c1b98e23 100644
> > --- a/arch/riscv/lib/asm-offsets.c
> > +++ b/arch/riscv/lib/asm-offsets.c
> > @@ -14,6 +14,7 @@
> >  int main(void)
> >  {
> >         DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
> > +       DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
> >  #ifndef CONFIG_XIP
> >         DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));  #endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c new file mode 100644 index 000000000000..1fce41490973
> > --- /dev/null
> > +++ b/arch/riscv/lib/fdt_fixup.c
> > @@ -0,0 +1,102 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2020 Western Digital Corporation or its affiliates
> > + *
> > + */
> > +
> > +#include <common.h>
> > +#include <fdt_support.h>
> > +#include <mapmem.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +/**
> > + * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
> > + * @src: Pointer to the source device tree from which reserved memory node
> > + *      needs to be copied.
> > + * @dst: Pointer to the destination device tree to which reserved memory node
> > + *      needs to be copied.
> > + *
> > + * Return: 0 on success or if source doesn't have reserved memory node.
> > + *        Error if copy process failed.
> > + */
> > +int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) {
> > +       u32 phandle;
> > +       struct fdt_memory pmp_mem;
> > +       fdt_addr_t addr;
> > +       fdt_size_t size;
> > +       int offset, node, err, rmem_offset;
> > +       bool nomap = true;
> > +       char basename[32] = {0};
> > +       int bname_len;
> > +       int max_len = sizeof(basename);
> > +       const char *name;
> > +       char *temp;
> > +
> > +       offset = fdt_path_offset(src, "/reserved-memory");
> > +       if (offset < 0) {
> > +               printf("No reserved memory region found in source FDT\n");
> > +               return 0;
> > +       }
> > +
> > +       fdt_for_each_subnode(node, src, offset) {
> > +               name = fdt_get_name(src, node, NULL);
> > +
> > +               addr = fdtdec_get_addr_size_auto_noparent(src, node,
> > +                                                         "reg", 0, &size,
> > +                                                         false);
> > +               if (addr == FDT_ADDR_T_NONE) {
> > +                       debug("failed to read address/size for %s\n", name);
> > +                       continue;
> > +               }
> > +               strncpy(basename, name, max_len);
> > +               temp = strchr(basename, '@');
> > +               if (temp) {
> > +                       bname_len = strnlen(basename, max_len) - strnlen(temp,
> > +                                                                      max_len);
> > +                       *(basename + bname_len) = '\0';
> > +               }
> > +               pmp_mem.start = addr;
> > +               pmp_mem.end = addr + size - 1;
> > +               err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
> > +                                                &phandle);
> > +               if (err < 0) {
> > +                       printf("failed to add reserved memory: %d\n", err);
> > +                       return err;
> > +               }
> > +               if (!fdt_getprop(src, node, "no-map", NULL))
> > +                       nomap = false;
> > +               if (nomap) {
> > +                       rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
> > +                       fdt_setprop_empty(dst, rmem_offset, "no-map");
> > +               }
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a
> > +board
> > + * @fdt: Pointer to the device tree in which reserved memory node needs to be
> > + *      added.
> > + *
> > + * In RISC-V, any board compiled with OF_SEPARATE needs to copy the
> > +reserved
> > + * memory node from the device tree provided by the firmware to the
> > +device tree
> > + * used by U-Boot. This is a common function that individual board
> > +fixup
> > + * functions can invoke.
> > + *
> > + * Return: 0 on success or error otherwise.
> > + */
> > +int riscv_board_reserved_mem_fixup(void *fdt) {
> > +       int err;
> > +       void *src_fdt_addr;
> > +
> > +       src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
> > +       err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
> > +       if (err < 0)
> > +               return err;
> > +
> > +       return 0;
> > +}
> > --
> > 2.25.1
> >
> > CONFIDENTIALITY NOTICE:
> >
> > This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.
> >
> > Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.
Rick Chen April 21, 2020, 8:25 a.m. UTC | #4
Hi Atish

> On Mon, Apr 20, 2020 at 1:41 AM Rick Chen <rickchen36 at gmail.com> wrote:
> >
> > Hi Atish
> >
> > > From: Atish Patra [mailto:atish.patra at wdc.com]
> > > Sent: Sunday, April 19, 2020 3:32 AM
> > > To: u-boot at lists.denx.de
> > > Cc: Atish Patra; Bin Meng; Anup Patel; Lukas Auer; Heinrich Schuchardt; agraf at csgraf.de; ard.biesheuvel at linaro.org; Marcus Comstedt; Paul Walmsley; Rick Jian-Zhi Chen(???); palmer at dabbelt.com
> > > Subject: [PATCH v6 3/6] riscv: Provide a mechanism to fix DT for reserved memory
> > >
> > > In RISC-V, M-mode software can reserve physical memory regions by setting appropriate physical memory protection (PMP) csr. As the PMP csr are accessible only in M-mode, S-mode U-Boot can not read this configuration directly. However, M-mode software can pass this information via reserved-memory node in device tree so that S-mode software can access this information.
> > >
> > > This patch provides a framework to copy to the reserved-memory node from one DT to another. This will be used to update the DT used by U-Boot and the DT passed to the next stage OS.
> > >
> > > Signed-off-by: Atish Patra <atish.patra at wdc.com>
> > > Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> > > ---
> > >  arch/riscv/cpu/start.S                |   1 +
> > >  arch/riscv/include/asm/global_data.h  |   1 +
> > >  arch/riscv/include/asm/u-boot-riscv.h |   2 +
> > >  arch/riscv/lib/Makefile               |   1 +
> > >  arch/riscv/lib/asm-offsets.c          |   1 +
> > >  arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
> > >  6 files changed, 108 insertions(+)
> > >  create mode 100644 arch/riscv/lib/fdt_fixup.c
> > >
> >
> > I am trying to applied Bin and your patch.
> > The sequence of apply is according to submit date.
> > This patch seem conflict with [PATCH v2 2/6] riscv: Merge unnecessary
> > SMP ifdefs in start.S of Bin
> > Can you rebase it and send again ?
> >
>
> Ok. I will rebase on top of Bin's series and resend.
>

Please rebase on u-boot-riscv/master.
I also applied Sean's patch today.

Thanks,
Rick

> > > diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 6b3ff99c3882..0282685c2906 100644
> > > --- a/arch/riscv/cpu/start.S
> > > +++ b/arch/riscv/cpu/start.S
> > > @@ -121,6 +121,7 @@ call_board_init_f_0:
> > >
> > >         jal     board_init_f_init_reserve
> > >
> > > +       SREG    s1, GD_FIRMWARE_FDT_ADDR(gp)
> > >         /* save the boot hart id to global_data */
> > >         SREG    tp, GD_BOOT_HART(gp)
> > >
> > > diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> > > index b74bd7e738bb..51ac8d1c98e2 100644
> > > --- a/arch/riscv/include/asm/global_data.h
> > > +++ b/arch/riscv/include/asm/global_data.h
> > > @@ -15,6 +15,7 @@
> > >  /* Architecture-specific global data */  struct arch_global_data {
> > >         long boot_hart;         /* boot hart id */
> > > +       phys_addr_t firmware_fdt_addr;
> > >  #ifdef CONFIG_SIFIVE_CLINT
> > >         void __iomem *clint;    /* clint base address */
> > >  #endif
> > > diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
> > > index 49febd588102..543a1688db8f 100644
> > > --- a/arch/riscv/include/asm/u-boot-riscv.h
> > > +++ b/arch/riscv/include/asm/u-boot-riscv.h
> > > @@ -17,5 +17,7 @@ int cleanup_before_linux(void);
> > >  /* board/.../... */
> > >  int board_init(void);
> > >  void board_quiesce_devices(void);
> > > +int riscv_board_reserved_mem_fixup(void *fdt); int
> > > +riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
> > >
> > >  #endif /* _U_BOOT_RISCV_H_ */
> > > diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index adadbf4bcbef..d132b59ce32c 100644
> > > --- a/arch/riscv/lib/Makefile
> > > +++ b/arch/riscv/lib/Makefile
> > > @@ -24,6 +24,7 @@ obj-y += reset.o
> > >  obj-y   += setjmp.o
> > >  obj-$(CONFIG_SMP) += smp.o
> > >  obj-$(CONFIG_SPL_BUILD)        += spl.o
> > > +obj-y   += fdt_fixup.o
> > >
> > >  # For building EFI apps
> > >  CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
> > > diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 4fa4fd371473..7301c1b98e23 100644
> > > --- a/arch/riscv/lib/asm-offsets.c
> > > +++ b/arch/riscv/lib/asm-offsets.c
> > > @@ -14,6 +14,7 @@
> > >  int main(void)
> > >  {
> > >         DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
> > > +       DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
> > >  #ifndef CONFIG_XIP
> > >         DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));  #endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c new file mode 100644 index 000000000000..1fce41490973
> > > --- /dev/null
> > > +++ b/arch/riscv/lib/fdt_fixup.c
> > > @@ -0,0 +1,102 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright (c) 2020 Western Digital Corporation or its affiliates
> > > + *
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <fdt_support.h>
> > > +#include <mapmem.h>
> > > +
> > > +DECLARE_GLOBAL_DATA_PTR;
> > > +
> > > +/**
> > > + * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
> > > + * @src: Pointer to the source device tree from which reserved memory node
> > > + *      needs to be copied.
> > > + * @dst: Pointer to the destination device tree to which reserved memory node
> > > + *      needs to be copied.
> > > + *
> > > + * Return: 0 on success or if source doesn't have reserved memory node.
> > > + *        Error if copy process failed.
> > > + */
> > > +int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) {
> > > +       u32 phandle;
> > > +       struct fdt_memory pmp_mem;
> > > +       fdt_addr_t addr;
> > > +       fdt_size_t size;
> > > +       int offset, node, err, rmem_offset;
> > > +       bool nomap = true;
> > > +       char basename[32] = {0};
> > > +       int bname_len;
> > > +       int max_len = sizeof(basename);
> > > +       const char *name;
> > > +       char *temp;
> > > +
> > > +       offset = fdt_path_offset(src, "/reserved-memory");
> > > +       if (offset < 0) {
> > > +               printf("No reserved memory region found in source FDT\n");
> > > +               return 0;
> > > +       }
> > > +
> > > +       fdt_for_each_subnode(node, src, offset) {
> > > +               name = fdt_get_name(src, node, NULL);
> > > +
> > > +               addr = fdtdec_get_addr_size_auto_noparent(src, node,
> > > +                                                         "reg", 0, &size,
> > > +                                                         false);
> > > +               if (addr == FDT_ADDR_T_NONE) {
> > > +                       debug("failed to read address/size for %s\n", name);
> > > +                       continue;
> > > +               }
> > > +               strncpy(basename, name, max_len);
> > > +               temp = strchr(basename, '@');
> > > +               if (temp) {
> > > +                       bname_len = strnlen(basename, max_len) - strnlen(temp,
> > > +                                                                      max_len);
> > > +                       *(basename + bname_len) = '\0';
> > > +               }
> > > +               pmp_mem.start = addr;
> > > +               pmp_mem.end = addr + size - 1;
> > > +               err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
> > > +                                                &phandle);
> > > +               if (err < 0) {
> > > +                       printf("failed to add reserved memory: %d\n", err);
> > > +                       return err;
> > > +               }
> > > +               if (!fdt_getprop(src, node, "no-map", NULL))
> > > +                       nomap = false;
> > > +               if (nomap) {
> > > +                       rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
> > > +                       fdt_setprop_empty(dst, rmem_offset, "no-map");
> > > +               }
> > > +       }
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +/**
> > > + * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a
> > > +board
> > > + * @fdt: Pointer to the device tree in which reserved memory node needs to be
> > > + *      added.
> > > + *
> > > + * In RISC-V, any board compiled with OF_SEPARATE needs to copy the
> > > +reserved
> > > + * memory node from the device tree provided by the firmware to the
> > > +device tree
> > > + * used by U-Boot. This is a common function that individual board
> > > +fixup
> > > + * functions can invoke.
> > > + *
> > > + * Return: 0 on success or error otherwise.
> > > + */
> > > +int riscv_board_reserved_mem_fixup(void *fdt) {
> > > +       int err;
> > > +       void *src_fdt_addr;
> > > +
> > > +       src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
> > > +       err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
> > > +       if (err < 0)
> > > +               return err;
> > > +
> > > +       return 0;
> > > +}
> > > --
> > > 2.25.1
> > >
Atish Patra April 21, 2020, 6:15 p.m. UTC | #5
On Tue, Apr 21, 2020 at 1:25 AM Rick Chen <rickchen36 at gmail.com> wrote:
>
> Hi Atish
>
> > On Mon, Apr 20, 2020 at 1:41 AM Rick Chen <rickchen36 at gmail.com> wrote:
> > >
> > > Hi Atish
> > >
> > > > From: Atish Patra [mailto:atish.patra at wdc.com]
> > > > Sent: Sunday, April 19, 2020 3:32 AM
> > > > To: u-boot at lists.denx.de
> > > > Cc: Atish Patra; Bin Meng; Anup Patel; Lukas Auer; Heinrich Schuchardt; agraf at csgraf.de; ard.biesheuvel at linaro.org; Marcus Comstedt; Paul Walmsley; Rick Jian-Zhi Chen(???); palmer at dabbelt.com
> > > > Subject: [PATCH v6 3/6] riscv: Provide a mechanism to fix DT for reserved memory
> > > >
> > > > In RISC-V, M-mode software can reserve physical memory regions by setting appropriate physical memory protection (PMP) csr. As the PMP csr are accessible only in M-mode, S-mode U-Boot can not read this configuration directly. However, M-mode software can pass this information via reserved-memory node in device tree so that S-mode software can access this information.
> > > >
> > > > This patch provides a framework to copy to the reserved-memory node from one DT to another. This will be used to update the DT used by U-Boot and the DT passed to the next stage OS.
> > > >
> > > > Signed-off-by: Atish Patra <atish.patra at wdc.com>
> > > > Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> > > > ---
> > > >  arch/riscv/cpu/start.S                |   1 +
> > > >  arch/riscv/include/asm/global_data.h  |   1 +
> > > >  arch/riscv/include/asm/u-boot-riscv.h |   2 +
> > > >  arch/riscv/lib/Makefile               |   1 +
> > > >  arch/riscv/lib/asm-offsets.c          |   1 +
> > > >  arch/riscv/lib/fdt_fixup.c            | 102 ++++++++++++++++++++++++++
> > > >  6 files changed, 108 insertions(+)
> > > >  create mode 100644 arch/riscv/lib/fdt_fixup.c
> > > >
> > >
> > > I am trying to applied Bin and your patch.
> > > The sequence of apply is according to submit date.
> > > This patch seem conflict with [PATCH v2 2/6] riscv: Merge unnecessary
> > > SMP ifdefs in start.S of Bin
> > > Can you rebase it and send again ?
> > >
> >
> > Ok. I will rebase on top of Bin's series and resend.
> >
>
> Please rebase on u-boot-riscv/master.
> I also applied Sean's patch today.
>

Done. Sent v7.

> Thanks,
> Rick
>
> > > > diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 6b3ff99c3882..0282685c2906 100644
> > > > --- a/arch/riscv/cpu/start.S
> > > > +++ b/arch/riscv/cpu/start.S
> > > > @@ -121,6 +121,7 @@ call_board_init_f_0:
> > > >
> > > >         jal     board_init_f_init_reserve
> > > >
> > > > +       SREG    s1, GD_FIRMWARE_FDT_ADDR(gp)
> > > >         /* save the boot hart id to global_data */
> > > >         SREG    tp, GD_BOOT_HART(gp)
> > > >
> > > > diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> > > > index b74bd7e738bb..51ac8d1c98e2 100644
> > > > --- a/arch/riscv/include/asm/global_data.h
> > > > +++ b/arch/riscv/include/asm/global_data.h
> > > > @@ -15,6 +15,7 @@
> > > >  /* Architecture-specific global data */  struct arch_global_data {
> > > >         long boot_hart;         /* boot hart id */
> > > > +       phys_addr_t firmware_fdt_addr;
> > > >  #ifdef CONFIG_SIFIVE_CLINT
> > > >         void __iomem *clint;    /* clint base address */
> > > >  #endif
> > > > diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
> > > > index 49febd588102..543a1688db8f 100644
> > > > --- a/arch/riscv/include/asm/u-boot-riscv.h
> > > > +++ b/arch/riscv/include/asm/u-boot-riscv.h
> > > > @@ -17,5 +17,7 @@ int cleanup_before_linux(void);
> > > >  /* board/.../... */
> > > >  int board_init(void);
> > > >  void board_quiesce_devices(void);
> > > > +int riscv_board_reserved_mem_fixup(void *fdt); int
> > > > +riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
> > > >
> > > >  #endif /* _U_BOOT_RISCV_H_ */
> > > > diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index adadbf4bcbef..d132b59ce32c 100644
> > > > --- a/arch/riscv/lib/Makefile
> > > > +++ b/arch/riscv/lib/Makefile
> > > > @@ -24,6 +24,7 @@ obj-y += reset.o
> > > >  obj-y   += setjmp.o
> > > >  obj-$(CONFIG_SMP) += smp.o
> > > >  obj-$(CONFIG_SPL_BUILD)        += spl.o
> > > > +obj-y   += fdt_fixup.o
> > > >
> > > >  # For building EFI apps
> > > >  CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
> > > > diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 4fa4fd371473..7301c1b98e23 100644
> > > > --- a/arch/riscv/lib/asm-offsets.c
> > > > +++ b/arch/riscv/lib/asm-offsets.c
> > > > @@ -14,6 +14,7 @@
> > > >  int main(void)
> > > >  {
> > > >         DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
> > > > +       DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
> > > >  #ifndef CONFIG_XIP
> > > >         DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));  #endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c new file mode 100644 index 000000000000..1fce41490973
> > > > --- /dev/null
> > > > +++ b/arch/riscv/lib/fdt_fixup.c
> > > > @@ -0,0 +1,102 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*
> > > > + * Copyright (c) 2020 Western Digital Corporation or its affiliates
> > > > + *
> > > > + */
> > > > +
> > > > +#include <common.h>
> > > > +#include <fdt_support.h>
> > > > +#include <mapmem.h>
> > > > +
> > > > +DECLARE_GLOBAL_DATA_PTR;
> > > > +
> > > > +/**
> > > > + * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
> > > > + * @src: Pointer to the source device tree from which reserved memory node
> > > > + *      needs to be copied.
> > > > + * @dst: Pointer to the destination device tree to which reserved memory node
> > > > + *      needs to be copied.
> > > > + *
> > > > + * Return: 0 on success or if source doesn't have reserved memory node.
> > > > + *        Error if copy process failed.
> > > > + */
> > > > +int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) {
> > > > +       u32 phandle;
> > > > +       struct fdt_memory pmp_mem;
> > > > +       fdt_addr_t addr;
> > > > +       fdt_size_t size;
> > > > +       int offset, node, err, rmem_offset;
> > > > +       bool nomap = true;
> > > > +       char basename[32] = {0};
> > > > +       int bname_len;
> > > > +       int max_len = sizeof(basename);
> > > > +       const char *name;
> > > > +       char *temp;
> > > > +
> > > > +       offset = fdt_path_offset(src, "/reserved-memory");
> > > > +       if (offset < 0) {
> > > > +               printf("No reserved memory region found in source FDT\n");
> > > > +               return 0;
> > > > +       }
> > > > +
> > > > +       fdt_for_each_subnode(node, src, offset) {
> > > > +               name = fdt_get_name(src, node, NULL);
> > > > +
> > > > +               addr = fdtdec_get_addr_size_auto_noparent(src, node,
> > > > +                                                         "reg", 0, &size,
> > > > +                                                         false);
> > > > +               if (addr == FDT_ADDR_T_NONE) {
> > > > +                       debug("failed to read address/size for %s\n", name);
> > > > +                       continue;
> > > > +               }
> > > > +               strncpy(basename, name, max_len);
> > > > +               temp = strchr(basename, '@');
> > > > +               if (temp) {
> > > > +                       bname_len = strnlen(basename, max_len) - strnlen(temp,
> > > > +                                                                      max_len);
> > > > +                       *(basename + bname_len) = '\0';
> > > > +               }
> > > > +               pmp_mem.start = addr;
> > > > +               pmp_mem.end = addr + size - 1;
> > > > +               err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
> > > > +                                                &phandle);
> > > > +               if (err < 0) {
> > > > +                       printf("failed to add reserved memory: %d\n", err);
> > > > +                       return err;
> > > > +               }
> > > > +               if (!fdt_getprop(src, node, "no-map", NULL))
> > > > +                       nomap = false;
> > > > +               if (nomap) {
> > > > +                       rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
> > > > +                       fdt_setprop_empty(dst, rmem_offset, "no-map");
> > > > +               }
> > > > +       }
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +/**
> > > > + * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a
> > > > +board
> > > > + * @fdt: Pointer to the device tree in which reserved memory node needs to be
> > > > + *      added.
> > > > + *
> > > > + * In RISC-V, any board compiled with OF_SEPARATE needs to copy the
> > > > +reserved
> > > > + * memory node from the device tree provided by the firmware to the
> > > > +device tree
> > > > + * used by U-Boot. This is a common function that individual board
> > > > +fixup
> > > > + * functions can invoke.
> > > > + *
> > > > + * Return: 0 on success or error otherwise.
> > > > + */
> > > > +int riscv_board_reserved_mem_fixup(void *fdt) {
> > > > +       int err;
> > > > +       void *src_fdt_addr;
> > > > +
> > > > +       src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
> > > > +       err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
> > > > +       if (err < 0)
> > > > +               return err;
> > > > +
> > > > +       return 0;
> > > > +}
> > > > --
> > > > 2.25.1
> > > >
diff mbox series

Patch

diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6b3ff99c3882..0282685c2906 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -121,6 +121,7 @@  call_board_init_f_0:
 
 	jal	board_init_f_init_reserve
 
+	SREG	s1, GD_FIRMWARE_FDT_ADDR(gp)
 	/* save the boot hart id to global_data */
 	SREG	tp, GD_BOOT_HART(gp)
 
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index b74bd7e738bb..51ac8d1c98e2 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -15,6 +15,7 @@ 
 /* Architecture-specific global data */
 struct arch_global_data {
 	long boot_hart;		/* boot hart id */
+	phys_addr_t firmware_fdt_addr;
 #ifdef CONFIG_SIFIVE_CLINT
 	void __iomem *clint;	/* clint base address */
 #endif
diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
index 49febd588102..543a1688db8f 100644
--- a/arch/riscv/include/asm/u-boot-riscv.h
+++ b/arch/riscv/include/asm/u-boot-riscv.h
@@ -17,5 +17,7 @@  int cleanup_before_linux(void);
 /* board/.../... */
 int board_init(void);
 void board_quiesce_devices(void);
+int riscv_board_reserved_mem_fixup(void *fdt);
+int riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
 
 #endif	/* _U_BOOT_RISCV_H_ */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index adadbf4bcbef..d132b59ce32c 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -24,6 +24,7 @@  obj-y	+= reset.o
 obj-y   += setjmp.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPL_BUILD)	+= spl.o
+obj-y   += fdt_fixup.o
 
 # For building EFI apps
 CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
index 4fa4fd371473..7301c1b98e23 100644
--- a/arch/riscv/lib/asm-offsets.c
+++ b/arch/riscv/lib/asm-offsets.c
@@ -14,6 +14,7 @@ 
 int main(void)
 {
 	DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
+	DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
 #ifndef CONFIG_XIP
 	DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));
 #endif
diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c
new file mode 100644
index 000000000000..1fce41490973
--- /dev/null
+++ b/arch/riscv/lib/fdt_fixup.c
@@ -0,0 +1,102 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates
+ *
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <mapmem.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
+ * @src: Pointer to the source device tree from which reserved memory node
+ *	 needs to be copied.
+ * @dst: Pointer to the destination device tree to which reserved memory node
+ *	 needs to be copied.
+ *
+ * Return: 0 on success or if source doesn't have reserved memory node.
+ *	   Error if copy process failed.
+ */
+int riscv_fdt_copy_resv_mem_node(const void *src, void *dst)
+{
+	u32 phandle;
+	struct fdt_memory pmp_mem;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	int offset, node, err, rmem_offset;
+	bool nomap = true;
+	char basename[32] = {0};
+	int bname_len;
+	int max_len = sizeof(basename);
+	const char *name;
+	char *temp;
+
+	offset = fdt_path_offset(src, "/reserved-memory");
+	if (offset < 0) {
+		printf("No reserved memory region found in source FDT\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(node, src, offset) {
+		name = fdt_get_name(src, node, NULL);
+
+		addr = fdtdec_get_addr_size_auto_noparent(src, node,
+							  "reg", 0, &size,
+							  false);
+		if (addr == FDT_ADDR_T_NONE) {
+			debug("failed to read address/size for %s\n", name);
+			continue;
+		}
+		strncpy(basename, name, max_len);
+		temp = strchr(basename, '@');
+		if (temp) {
+			bname_len = strnlen(basename, max_len) - strnlen(temp,
+								       max_len);
+			*(basename + bname_len) = '\0';
+		}
+		pmp_mem.start = addr;
+		pmp_mem.end = addr + size - 1;
+		err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
+						 &phandle);
+		if (err < 0) {
+			printf("failed to add reserved memory: %d\n", err);
+			return err;
+		}
+		if (!fdt_getprop(src, node, "no-map", NULL))
+			nomap = false;
+		if (nomap) {
+			rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
+			fdt_setprop_empty(dst, rmem_offset, "no-map");
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a board
+ * @fdt: Pointer to the device tree in which reserved memory node needs to be
+ *	 added.
+ *
+ * In RISC-V, any board compiled with OF_SEPARATE needs to copy the reserved
+ * memory node from the device tree provided by the firmware to the device tree
+ * used by U-Boot. This is a common function that individual board fixup
+ * functions can invoke.
+ *
+ * Return: 0 on success or error otherwise.
+ */
+int riscv_board_reserved_mem_fixup(void *fdt)
+{
+	int err;
+	void *src_fdt_addr;
+
+	src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
+	err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
+	if (err < 0)
+		return err;
+
+	return 0;
+}