diff mbox series

[v3,17/27] lmb: do away with arch_lmb_reserve()

Message ID 20240821105839.2870293-18-sughosh.ganu@linaro.org
State Superseded
Headers show
Series Make LMB memory map global and persistent | expand

Commit Message

Sughosh Ganu Aug. 21, 2024, 10:58 a.m. UTC
All of the current definitions of arch_lmb_reserve() are doing the
same thing -- reserve the region of memory occupied by U-Boot,
starting from the current stack address to the ram_top. Introduce a
function lmb_reserve_uboot_region() which does this, and do away with
the arch_lmb_reserve() function.

Instead of using the current value of stack pointer for starting the
reserved region, have a fixed value, considering the stack size config
value.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
Changes since V2:
* Remove the definitions of arch_lmb_reserve() and
  arch_lmb_reserve_generic() functions.
* Introduce a new function lmb_reserve_uboot_region() and call it from
  lmb_reserve_common().

 arch/arc/lib/cache.c        | 14 -------
 arch/arm/lib/stack.c        | 14 -------
 arch/m68k/lib/bootm.c       | 17 --------
 arch/microblaze/lib/bootm.c | 14 -------
 arch/mips/lib/bootm.c       | 15 -------
 arch/nios2/lib/bootm.c      | 13 ------
 arch/powerpc/lib/bootm.c    |  9 ----
 arch/riscv/lib/bootm.c      | 13 ------
 arch/sh/lib/bootm.c         | 13 ------
 arch/x86/lib/bootm.c        | 18 --------
 arch/xtensa/lib/bootm.c     | 13 ------
 include/lmb.h               |  2 -
 lib/lmb.c                   | 83 ++++++++++++++++++-------------------
 13 files changed, 41 insertions(+), 197 deletions(-)

Comments

Simon Glass Aug. 23, 2024, 8:47 p.m. UTC | #1
Hi Sughosh,

On Wed, 21 Aug 2024 at 05:00, Sughosh Ganu <sughosh.ganu@linaro.org> wrote:
>
> All of the current definitions of arch_lmb_reserve() are doing the
> same thing -- reserve the region of memory occupied by U-Boot,
> starting from the current stack address to the ram_top. Introduce a
> function lmb_reserve_uboot_region() which does this, and do away with
> the arch_lmb_reserve() function.
>
> Instead of using the current value of stack pointer for starting the
> reserved region, have a fixed value, considering the stack size config
> value.nit
>
> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> ---
> Changes since V2:
> * Remove the definitions of arch_lmb_reserve() and
>   arch_lmb_reserve_generic() functions.
> * Introduce a new function lmb_reserve_uboot_region() and call it from
>   lmb_reserve_common().
>
>  arch/arc/lib/cache.c        | 14 -------
>  arch/arm/lib/stack.c        | 14 -------
>  arch/m68k/lib/bootm.c       | 17 --------
>  arch/microblaze/lib/bootm.c | 14 -------
>  arch/mips/lib/bootm.c       | 15 -------
>  arch/nios2/lib/bootm.c      | 13 ------
>  arch/powerpc/lib/bootm.c    |  9 ----
>  arch/riscv/lib/bootm.c      | 13 ------
>  arch/sh/lib/bootm.c         | 13 ------
>  arch/x86/lib/bootm.c        | 18 --------
>  arch/xtensa/lib/bootm.c     | 13 ------
>  include/lmb.h               |  2 -
>  lib/lmb.c                   | 83 ++++++++++++++++++-------------------
>  13 files changed, 41 insertions(+), 197 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

question below

[..]

> diff --git a/include/lmb.h b/include/lmb.h
> index e6c6f1cdcd..6e435bd35c 100644
> --- a/include/lmb.h
> +++ b/include/lmb.h
> @@ -108,8 +108,6 @@ void lmb_dump_all(void);
>  void lmb_dump_all_force(void);
>
>  void board_lmb_reserve(void);
> -void arch_lmb_reserve(void);
> -void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align);
>
>  #if CONFIG_IS_ENABLED(UNIT_TEST)

There is no need to do this in the header file, BTW. It will cause a
link error if someone uses it by mistake.

>  struct lmb *lmb_get(void);
> diff --git a/lib/lmb.c b/lib/lmb.c
> index e26e329248..1116b2b868 100644
> --- a/lib/lmb.c
> +++ b/lib/lmb.c
[..]
> @@ -215,10 +179,50 @@ static __maybe_unused int efi_lmb_reserve(void)
>         return 0;
>  }
>
> +static void lmb_reserve_uboot_region(void)
> +{
> +       int bank;
> +       ulong end, bank_end;
> +       phys_addr_t rsv_start;
> +
> +       rsv_start = gd->start_addr_sp - CONFIG_STACK_SIZE;
> +       end = gd->ram_top;
> +
> +       /*
> +        * Reserve memory from aligned address below the bottom of U-Boot stack
> +        * until end of RAM area to prevent LMB from overwriting that memory.
> +        */
> +       debug("## Current stack ends at 0x%08lx ", (ulong)rsv_start);
> +
> +       /* adjust sp by 4K to be safe */
> +       rsv_start -= 16384;

Should that be SZ_4K ?

> +       for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
> +               if (!gd->bd->bi_dram[bank].size ||
> +                   rsv_start < gd->bd->bi_dram[bank].start)
> +                       continue;
> +               /* Watch out for RAM at end of address space! */
> +               bank_end = gd->bd->bi_dram[bank].start +
> +                       gd->bd->bi_dram[bank].size - 1;
> +               if (rsv_start > bank_end)
> +                       continue;
> +               if (bank_end > end)
> +                       bank_end = end - 1;
> +
> +               lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1,
> +                                 LMB_NOOVERWRITE);
> +
> +               if (gd->flags & GD_FLG_SKIP_RELOC)
> +                       lmb_reserve_flags((phys_addr_t)(uintptr_t)_start,
> +                                   gd->mon_len, LMB_NOOVERWRITE);
> +
> +               break;
> +       }
> +}
> +
>  static void lmb_reserve_common(void *fdt_blob)
>  {
> -       arch_lmb_reserve();
>         board_lmb_reserve();
> +       lmb_reserve_uboot_region();
>
>         if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob)
>                 boot_fdt_add_mem_rsv_regions(fdt_blob);
> @@ -689,11 +693,6 @@ __weak void board_lmb_reserve(void)
>         /* please define platform specific board_lmb_reserve() */
>  }
>
> -__weak void arch_lmb_reserve(void)
> -{
> -       /* please define platform specific arch_lmb_reserve() */
> -}
> -
>  static int lmb_setup(void)
>  {
>         bool ret;
> --
> 2.34.1
>

Regards,
Simon
Sughosh Ganu Aug. 24, 2024, 5:34 a.m. UTC | #2
On Sat, 24 Aug 2024 at 02:17, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Sughosh,
>
> On Wed, 21 Aug 2024 at 05:00, Sughosh Ganu <sughosh.ganu@linaro.org> wrote:
> >
> > All of the current definitions of arch_lmb_reserve() are doing the
> > same thing -- reserve the region of memory occupied by U-Boot,
> > starting from the current stack address to the ram_top. Introduce a
> > function lmb_reserve_uboot_region() which does this, and do away with
> > the arch_lmb_reserve() function.
> >
> > Instead of using the current value of stack pointer for starting the
> > reserved region, have a fixed value, considering the stack size config
> > value.nit
> >
> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > ---
> > Changes since V2:
> > * Remove the definitions of arch_lmb_reserve() and
> >   arch_lmb_reserve_generic() functions.
> > * Introduce a new function lmb_reserve_uboot_region() and call it from
> >   lmb_reserve_common().
> >
> >  arch/arc/lib/cache.c        | 14 -------
> >  arch/arm/lib/stack.c        | 14 -------
> >  arch/m68k/lib/bootm.c       | 17 --------
> >  arch/microblaze/lib/bootm.c | 14 -------
> >  arch/mips/lib/bootm.c       | 15 -------
> >  arch/nios2/lib/bootm.c      | 13 ------
> >  arch/powerpc/lib/bootm.c    |  9 ----
> >  arch/riscv/lib/bootm.c      | 13 ------
> >  arch/sh/lib/bootm.c         | 13 ------
> >  arch/x86/lib/bootm.c        | 18 --------
> >  arch/xtensa/lib/bootm.c     | 13 ------
> >  include/lmb.h               |  2 -
> >  lib/lmb.c                   | 83 ++++++++++++++++++-------------------
> >  13 files changed, 41 insertions(+), 197 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> question below
>
> [..]
>
> > diff --git a/include/lmb.h b/include/lmb.h
> > index e6c6f1cdcd..6e435bd35c 100644
> > --- a/include/lmb.h
> > +++ b/include/lmb.h
> > @@ -108,8 +108,6 @@ void lmb_dump_all(void);
> >  void lmb_dump_all_force(void);
> >
> >  void board_lmb_reserve(void);
> > -void arch_lmb_reserve(void);
> > -void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align);
> >
> >  #if CONFIG_IS_ENABLED(UNIT_TEST)
>
> There is no need to do this in the header file, BTW. It will cause a
> link error if someone uses it by mistake.

Okay

>
> >  struct lmb *lmb_get(void);
> > diff --git a/lib/lmb.c b/lib/lmb.c
> > index e26e329248..1116b2b868 100644
> > --- a/lib/lmb.c
> > +++ b/lib/lmb.c
> [..]
> > @@ -215,10 +179,50 @@ static __maybe_unused int efi_lmb_reserve(void)
> >         return 0;
> >  }
> >
> > +static void lmb_reserve_uboot_region(void)
> > +{
> > +       int bank;
> > +       ulong end, bank_end;
> > +       phys_addr_t rsv_start;
> > +
> > +       rsv_start = gd->start_addr_sp - CONFIG_STACK_SIZE;
> > +       end = gd->ram_top;
> > +
> > +       /*
> > +        * Reserve memory from aligned address below the bottom of U-Boot stack
> > +        * until end of RAM area to prevent LMB from overwriting that memory.
> > +        */
> > +       debug("## Current stack ends at 0x%08lx ", (ulong)rsv_start);
> > +
> > +       /* adjust sp by 4K to be safe */
> > +       rsv_start -= 16384;
>
> Should that be SZ_4K ?

It should be SZ_16K. This is using the highest value that was being
used by the different architectures. I will fix the comment. Thanks.

-sughosh

>
> > +       for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
> > +               if (!gd->bd->bi_dram[bank].size ||
> > +                   rsv_start < gd->bd->bi_dram[bank].start)
> > +                       continue;
> > +               /* Watch out for RAM at end of address space! */
> > +               bank_end = gd->bd->bi_dram[bank].start +
> > +                       gd->bd->bi_dram[bank].size - 1;
> > +               if (rsv_start > bank_end)
> > +                       continue;
> > +               if (bank_end > end)
> > +                       bank_end = end - 1;
> > +
> > +               lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1,
> > +                                 LMB_NOOVERWRITE);
> > +
> > +               if (gd->flags & GD_FLG_SKIP_RELOC)
> > +                       lmb_reserve_flags((phys_addr_t)(uintptr_t)_start,
> > +                                   gd->mon_len, LMB_NOOVERWRITE);
> > +
> > +               break;
> > +       }
> > +}
> > +
> >  static void lmb_reserve_common(void *fdt_blob)
> >  {
> > -       arch_lmb_reserve();
> >         board_lmb_reserve();
> > +       lmb_reserve_uboot_region();
> >
> >         if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob)
> >                 boot_fdt_add_mem_rsv_regions(fdt_blob);
> > @@ -689,11 +693,6 @@ __weak void board_lmb_reserve(void)
> >         /* please define platform specific board_lmb_reserve() */
> >  }
> >
> > -__weak void arch_lmb_reserve(void)
> > -{
> > -       /* please define platform specific arch_lmb_reserve() */
> > -}
> > -
> >  static int lmb_setup(void)
> >  {
> >         bool ret;
> > --
> > 2.34.1
> >
>
> Regards,
> Simon
diff mbox series

Patch

diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 5151af917a..5169fc627f 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -10,7 +10,6 @@ 
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <linux/log2.h>
-#include <lmb.h>
 #include <asm/arcregs.h>
 #include <asm/arc-bcr.h>
 #include <asm/cache.h>
@@ -820,16 +819,3 @@  void sync_n_cleanup_cache_all(void)
 
 	__ic_entire_invalidate();
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mov %0, sp" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/arch/arm/lib/stack.c b/arch/arm/lib/stack.c
index 87d5c962d7..2b21ec0734 100644
--- a/arch/arm/lib/stack.c
+++ b/arch/arm/lib/stack.c
@@ -11,7 +11,6 @@ 
  * Marius Groeger <mgroeger@sysgo.de>
  */
 #include <init.h>
-#include <lmb.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -33,16 +32,3 @@  int arch_reserve_stacks(void)
 
 	return 0;
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mov %0, sp" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 16384);
-}
diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c
index eb220d178d..06854e1442 100644
--- a/arch/m68k/lib/bootm.c
+++ b/arch/m68k/lib/bootm.c
@@ -9,7 +9,6 @@ 
 #include <command.h>
 #include <env.h>
 #include <image.h>
-#include <lmb.h>
 #include <log.h>
 #include <asm/global_data.h>
 #include <u-boot/zlib.h>
@@ -27,14 +26,8 @@  DECLARE_GLOBAL_DATA_PTR;
 #define LINUX_MAX_ENVS		256
 #define LINUX_MAX_ARGS		256
 
-static ulong get_sp (void);
 static void set_clocks_in_mhz (struct bd_info *kbd);
 
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 1024);
-}
-
 int do_bootm_linux(int flag, struct bootm_info *bmi)
 {
 	struct bootm_headers *images = bmi->images;
@@ -88,16 +81,6 @@  error:
 	return 1;
 }
 
-static ulong get_sp (void)
-{
-	ulong sp;
-
-	asm("movel %%a7, %%d0\n"
-	    "movel %%d0, %0\n": "=d"(sp): :"%d0");
-
-	return sp;
-}
-
 static void set_clocks_in_mhz (struct bd_info *kbd)
 {
 	char *s;
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c
index ce96bca28f..4879a41aab 100644
--- a/arch/microblaze/lib/bootm.c
+++ b/arch/microblaze/lib/bootm.c
@@ -15,7 +15,6 @@ 
 #include <fdt_support.h>
 #include <hang.h>
 #include <image.h>
-#include <lmb.h>
 #include <log.h>
 #include <asm/cache.h>
 #include <asm/global_data.h>
@@ -24,19 +23,6 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("addik %0, r1, 0" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
-
 static void boot_jump_linux(struct bootm_headers *images, int flag)
 {
 	void (*thekernel)(char *cmdline, ulong rd, ulong dt);
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 8fb3a3923f..8719510002 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -9,7 +9,6 @@ 
 #include <env.h>
 #include <image.h>
 #include <fdt_support.h>
-#include <lmb.h>
 #include <log.h>
 #include <asm/addrspace.h>
 #include <asm/global_data.h>
@@ -28,20 +27,6 @@  static char **linux_env;
 static char *linux_env_p;
 static int linux_env_idx;
 
-static ulong arch_get_sp(void)
-{
-	ulong ret;
-
-	__asm__ __volatile__("move %0, $sp" : "=r"(ret) : );
-
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(arch_get_sp(), gd->ram_top, 4096);
-}
-
 static void linux_cmdline_init(void)
 {
 	linux_argc = 1;
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c
index d33d45d28f..71319839ba 100644
--- a/arch/nios2/lib/bootm.c
+++ b/arch/nios2/lib/bootm.c
@@ -64,16 +64,3 @@  int do_bootm_linux(int flag, struct bootm_info *bmi)
 
 	return 1;
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mov %0, sp" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 5402e0bb35..4375d80154 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -36,7 +36,6 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static ulong get_sp (void);
 extern void ft_fixup_num_cores(void *blob);
 static void set_clocks_in_mhz (struct bd_info *kbd);
 
@@ -210,14 +209,6 @@  int do_bootm_linux(int flag, struct bootm_info *bmi)
 	return 0;
 }
 
-static ulong get_sp (void)
-{
-	ulong sp;
-
-	asm( "mr %0,1": "=r"(sp) : );
-	return sp;
-}
-
 static void set_clocks_in_mhz (struct bd_info *kbd)
 {
 	char	*s;
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index bbf62f9e05..82502972ee 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -133,16 +133,3 @@  int do_bootm_vxworks(int flag, struct bootm_info *bmi)
 {
 	return do_bootm_linux(flag, bmi);
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mv %0, sp" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c
index 44ac05988c..bb0f59e0aa 100644
--- a/arch/sh/lib/bootm.c
+++ b/arch/sh/lib/bootm.c
@@ -101,16 +101,3 @@  int do_bootm_linux(int flag, struct bootm_info *bmi)
 	/* does not return */
 	return 1;
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mov r15, %0" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 114b31012e..55f581836d 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -253,21 +253,3 @@  int do_bootm_linux(int flag, struct bootm_info *bmi)
 
 	return boot_jump_linux(images);
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-#if CONFIG_IS_ENABLED(X86_64)
-	asm("mov %%rsp, %0" : "=r"(ret) : );
-#else
-	asm("mov %%esp, %0" : "=r"(ret) : );
-#endif
-
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c
index bdbd6d4692..2958f20739 100644
--- a/arch/xtensa/lib/bootm.c
+++ b/arch/xtensa/lib/bootm.c
@@ -197,16 +197,3 @@  int do_bootm_linux(int flag, struct bootm_info *bmi)
 
 	return 1;
 }
-
-static ulong get_sp(void)
-{
-	ulong ret;
-
-	asm("mov %0, a1" : "=r"(ret) : );
-	return ret;
-}
-
-void arch_lmb_reserve(void)
-{
-	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
-}
diff --git a/include/lmb.h b/include/lmb.h
index e6c6f1cdcd..6e435bd35c 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -108,8 +108,6 @@  void lmb_dump_all(void);
 void lmb_dump_all_force(void);
 
 void board_lmb_reserve(void);
-void arch_lmb_reserve(void);
-void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align);
 
 #if CONFIG_IS_ENABLED(UNIT_TEST)
 struct lmb *lmb_get(void);
diff --git a/lib/lmb.c b/lib/lmb.c
index e26e329248..1116b2b868 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -147,42 +147,6 @@  static void lmb_fix_over_lap_regions(struct alist *lmb_rgn_lst,
 	lmb_remove_region(lmb_rgn_lst, r2);
 }
 
-void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align)
-{
-	ulong bank_end;
-	int bank;
-
-	/*
-	 * Reserve memory from aligned address below the bottom of U-Boot stack
-	 * until end of U-Boot area using LMB to prevent U-Boot from overwriting
-	 * that memory.
-	 */
-	debug("## Current stack ends at 0x%08lx ", sp);
-
-	/* adjust sp by 4K to be safe */
-	sp -= align;
-	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
-		if (!gd->bd->bi_dram[bank].size ||
-		    sp < gd->bd->bi_dram[bank].start)
-			continue;
-		/* Watch out for RAM at end of address space! */
-		bank_end = gd->bd->bi_dram[bank].start +
-			gd->bd->bi_dram[bank].size - 1;
-		if (sp > bank_end)
-			continue;
-		if (bank_end > end)
-			bank_end = end - 1;
-
-		lmb_reserve_flags(sp, bank_end - sp + 1, LMB_NOOVERWRITE);
-
-		if (gd->flags & GD_FLG_SKIP_RELOC)
-			lmb_reserve_flags((phys_addr_t)(uintptr_t)_start,
-				    gd->mon_len, LMB_NOOVERWRITE);
-
-		break;
-	}
-}
-
 /**
  * efi_lmb_reserve() - add reservations for EFI memory
  *
@@ -215,10 +179,50 @@  static __maybe_unused int efi_lmb_reserve(void)
 	return 0;
 }
 
+static void lmb_reserve_uboot_region(void)
+{
+	int bank;
+	ulong end, bank_end;
+	phys_addr_t rsv_start;
+
+	rsv_start = gd->start_addr_sp - CONFIG_STACK_SIZE;
+	end = gd->ram_top;
+
+	/*
+	 * Reserve memory from aligned address below the bottom of U-Boot stack
+	 * until end of RAM area to prevent LMB from overwriting that memory.
+	 */
+	debug("## Current stack ends at 0x%08lx ", (ulong)rsv_start);
+
+	/* adjust sp by 4K to be safe */
+	rsv_start -= 16384;
+	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+		if (!gd->bd->bi_dram[bank].size ||
+		    rsv_start < gd->bd->bi_dram[bank].start)
+			continue;
+		/* Watch out for RAM at end of address space! */
+		bank_end = gd->bd->bi_dram[bank].start +
+			gd->bd->bi_dram[bank].size - 1;
+		if (rsv_start > bank_end)
+			continue;
+		if (bank_end > end)
+			bank_end = end - 1;
+
+		lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1,
+				  LMB_NOOVERWRITE);
+
+		if (gd->flags & GD_FLG_SKIP_RELOC)
+			lmb_reserve_flags((phys_addr_t)(uintptr_t)_start,
+				    gd->mon_len, LMB_NOOVERWRITE);
+
+		break;
+	}
+}
+
 static void lmb_reserve_common(void *fdt_blob)
 {
-	arch_lmb_reserve();
 	board_lmb_reserve();
+	lmb_reserve_uboot_region();
 
 	if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob)
 		boot_fdt_add_mem_rsv_regions(fdt_blob);
@@ -689,11 +693,6 @@  __weak void board_lmb_reserve(void)
 	/* please define platform specific board_lmb_reserve() */
 }
 
-__weak void arch_lmb_reserve(void)
-{
-	/* please define platform specific arch_lmb_reserve() */
-}
-
 static int lmb_setup(void)
 {
 	bool ret;