lmb: make LMB memory map persistent and global

The current LMB API's for allocating and reserving memory use a
per-caller based memory view. Memory allocated by a caller can then be
overwritten by another caller. Make these allocations and reservations
persistent using the alloced list data structure.

Two alloced lists are declared -- one for the available(free) memory,
and one for the used memory. Once full, the list can then be extended
at runtime.

[sjg: Use a stack to store pointer of lmb struct when running lmb tests]

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
[sjg: Optimise the logic to add a region in lmb_add_region_flags()]
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 22e7488..5151af9 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -829,7 +829,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	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 ea1b937..87d5c96 100644
--- a/arch/arm/lib/stack.c
+++ b/arch/arm/lib/stack.c
@@ -42,7 +42,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 16384);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 16384);
 }
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index 8bace30..213390d 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -773,23 +773,22 @@
 
 int board_late_init(void)
 {
-	struct lmb lmb;
 	u32 status = 0;
 
-	lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+	lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob);
 
 	/* somewhat based on the Linux Kernel boot requirements:
 	 * align by 2M and maximal FDT size 2M
 	 */
-	status |= env_set_hex("loadaddr", lmb_alloc(&lmb, SZ_1G, SZ_2M));
-	status |= env_set_hex("fdt_addr_r", lmb_alloc(&lmb, SZ_2M, SZ_2M));
-	status |= env_set_hex("kernel_addr_r", lmb_alloc(&lmb, SZ_128M, SZ_2M));
-	status |= env_set_hex("ramdisk_addr_r", lmb_alloc(&lmb, SZ_1G, SZ_2M));
+	status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M));
+	status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M));
+	status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M));
+	status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M));
 	status |= env_set_hex("kernel_comp_addr_r",
-			      lmb_alloc(&lmb, KERNEL_COMP_SIZE, SZ_2M));
+			      lmb_alloc(KERNEL_COMP_SIZE, SZ_2M));
 	status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
-	status |= env_set_hex("scriptaddr", lmb_alloc(&lmb, SZ_4M, SZ_2M));
-	status |= env_set_hex("pxefile_addr_r", lmb_alloc(&lmb, SZ_4M, SZ_2M));
+	status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M));
+	status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M));
 
 	if (status)
 		log_warning("late_init: Failed to set run time variables\n");
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index b439a19..a63c8be 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -275,24 +275,23 @@
 
 #define KERNEL_COMP_SIZE	SZ_64M
 
-#define addr_alloc(lmb, size) lmb_alloc(lmb, size, SZ_2M)
+#define addr_alloc(size) lmb_alloc(size, SZ_2M)
 
 /* Stolen from arch/arm/mach-apple/board.c */
 int board_late_init(void)
 {
-	struct lmb lmb;
 	u32 status = 0;
 
-	lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+	lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob);
 
 	/* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */
-	status |= env_set_hex("kernel_addr_r", addr_alloc(&lmb, SZ_128M));
-	status |= env_set_hex("ramdisk_addr_r", addr_alloc(&lmb, SZ_128M));
-	status |= env_set_hex("kernel_comp_addr_r", addr_alloc(&lmb, KERNEL_COMP_SIZE));
+	status |= env_set_hex("kernel_addr_r", addr_alloc(SZ_128M));
+	status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M));
+	status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE));
 	status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
-	status |= env_set_hex("scriptaddr", addr_alloc(&lmb, SZ_4M));
-	status |= env_set_hex("pxefile_addr_r", addr_alloc(&lmb, SZ_4M));
-	status |= env_set_hex("fdt_addr_r", addr_alloc(&lmb, SZ_2M));
+	status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M));
+	status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M));
+	status |= env_set_hex("fdt_addr_r", addr_alloc(SZ_2M));
 
 	if (status)
 		log_warning("%s: Failed to set run time variables\n", __func__);
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index 6024959..e8b0a38 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -47,7 +47,6 @@
 {
 	phys_size_t size;
 	phys_addr_t reg;
-	struct lmb lmb;
 
 	if (!total_size)
 		return gd->ram_top;
@@ -59,12 +58,11 @@
 	gd->ram_top = clamp_val(gd->ram_top, 0, SZ_4G - 1);
 
 	/* found enough not-reserved memory to relocated U-Boot */
-	lmb_init(&lmb);
-	lmb_add(&lmb, gd->ram_base, gd->ram_top - gd->ram_base);
-	boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
+	lmb_add(gd->ram_base, gd->ram_top - gd->ram_base);
+	boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob);
 	/* add 8M for reserved memory for display, fdt, gd,... */
 	size = ALIGN(SZ_8M + CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE),
-	reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
+	reg = lmb_alloc(size, MMU_SECTION_SIZE);
 
 	if (!reg)
 		reg = gd->ram_top - size;
diff --git a/arch/arm/mach-stm32mp/stm32mp1/cpu.c b/arch/arm/mach-stm32mp/stm32mp1/cpu.c
index 478c3ef..a913737 100644
--- a/arch/arm/mach-stm32mp/stm32mp1/cpu.c
+++ b/arch/arm/mach-stm32mp/stm32mp1/cpu.c
@@ -30,8 +30,6 @@
  */
 u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000);
 
-struct lmb lmb;
-
 u32 get_bootmode(void)
 {
 	/* read bootmode from TAMP backup register */
@@ -80,7 +78,7 @@
 	     i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT);
 	     i++) {
 		option = DCACHE_DEFAULT_OPTION;
-		if (use_lmb && lmb_is_reserved_flags(&lmb, i << MMU_SECTION_SHIFT, LMB_NOMAP))
+		if (use_lmb && lmb_is_reserved_flags(i << MMU_SECTION_SHIFT, LMB_NOMAP))
 			option = 0; /* INVALID ENTRY in TLB */
 		set_section_dcache(i, option);
 	}
@@ -144,7 +142,7 @@
 void enable_caches(void)
 {
 	/* parse device tree when data cache is still activated */
-	lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+	lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob);
 
 	/* I-cache is already enabled in start.S: icache_enable() not needed */
 
diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c
index f2d02e4..aee95f1 100644
--- a/arch/m68k/lib/bootm.c
+++ b/arch/m68k/lib/bootm.c
@@ -30,9 +30,9 @@
 static ulong get_sp (void);
 static void set_clocks_in_mhz (struct bd_info *kbd);
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 1024);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 1024);
 }
 
 int do_bootm_linux(int flag, struct bootm_info *bmi)
@@ -41,7 +41,6 @@
 	int ret;
 	struct bd_info  *kbd;
 	void  (*kernel) (struct bd_info *, ulong, ulong, ulong, ulong);
-	struct lmb *lmb = &images->lmb;
 
 	/*
 	 * allow the PREP bootm subcommand, it is required for bootm to work
@@ -53,7 +52,7 @@
 		return 1;
 
 	/* allocate space for kernel copy of board info */
-	ret = boot_get_kbd (lmb, &kbd);
+	ret = boot_get_kbd(&kbd);
 	if (ret) {
 		puts("ERROR with allocation of kernel bd\n");
 		goto error;
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c
index cbe9d85..ce96bca 100644
--- a/arch/microblaze/lib/bootm.c
+++ b/arch/microblaze/lib/bootm.c
@@ -32,9 +32,9 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
 }
 
 static void boot_jump_linux(struct bootm_headers *images, int flag)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index adb6b6c..8fb3a39 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -37,9 +37,9 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, arch_get_sp(), gd->ram_top, 4096);
+	arch_lmb_reserve_generic(arch_get_sp(), gd->ram_top, 4096);
 }
 
 static void linux_cmdline_init(void)
@@ -225,9 +225,8 @@
 	}
 
 #if CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && CONFIG_IS_ENABLED(OF_LIBFDT)
-	boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
-	return boot_relocate_fdt(&images->lmb, &images->ft_addr,
-		&images->ft_len);
+	boot_fdt_add_mem_rsv_regions(images->ft_addr);
+	return boot_relocate_fdt(&images->ft_addr, &images->ft_len);
 #else
 	return 0;
 #endif
@@ -248,7 +247,7 @@
 	images->initrd_start = virt_to_phys((void *)images->initrd_start);
 	images->initrd_end = virt_to_phys((void *)images->initrd_end);
 
-	return image_setup_libfdt(images, images->ft_addr, &images->lmb);
+	return image_setup_libfdt(images, images->ft_addr, true);
 }
 
 static void boot_prep_linux(struct bootm_headers *images)
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c
index ce939ff..d33d45d 100644
--- a/arch/nios2/lib/bootm.c
+++ b/arch/nios2/lib/bootm.c
@@ -73,7 +73,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c
index 03f801e..bed465c 100644
--- a/arch/powerpc/cpu/mpc85xx/mp.c
+++ b/arch/powerpc/cpu/mpc85xx/mp.c
@@ -408,11 +408,11 @@
 }
 #endif
 
-void cpu_mp_lmb_reserve(struct lmb *lmb)
+void cpu_mp_lmb_reserve(void)
 {
 	u32 bootpg = determine_mp_bootpg(NULL);
 
-	lmb_reserve(lmb, bootpg, 4096);
+	lmb_reserve(bootpg, 4096);
 }
 
 void setup_mp(void)
diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h
index 8dacd27..b3f59be 100644
--- a/arch/powerpc/include/asm/mp.h
+++ b/arch/powerpc/include/asm/mp.h
@@ -6,10 +6,8 @@
 #ifndef _ASM_MP_H_
 #define _ASM_MP_H_
 
-#include <lmb.h>
-
 void setup_mp(void);
-void cpu_mp_lmb_reserve(struct lmb *lmb);
+void cpu_mp_lmb_reserve(void);
 u32 determine_mp_bootpg(unsigned int *pagesize);
 int is_core_disabled(int nr);
 
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 61e0872..752f72f 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -116,7 +116,7 @@
 	return;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
 	phys_size_t bootm_size;
 	ulong size, bootmap_base;
@@ -139,13 +139,13 @@
 		ulong base = bootmap_base + size;
 		printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n",
 		       size, (unsigned long long)bootm_size);
-		lmb_reserve(lmb, base, bootm_size - size);
+		lmb_reserve(base, bootm_size - size);
 	}
 
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
 
 #ifdef CONFIG_MP
-	cpu_mp_lmb_reserve(lmb);
+	cpu_mp_lmb_reserve();
 #endif
 
 	return;
@@ -166,7 +166,6 @@
 static int boot_cmdline_linux(struct bootm_headers *images)
 {
 	ulong of_size = images->ft_len;
-	struct lmb *lmb = &images->lmb;
 	ulong *cmd_start = &images->cmdline_start;
 	ulong *cmd_end = &images->cmdline_end;
 
@@ -174,7 +173,7 @@
 
 	if (!of_size) {
 		/* allocate space and init command line */
-		ret = boot_get_cmdline (lmb, cmd_start, cmd_end);
+		ret = boot_get_cmdline(cmd_start, cmd_end);
 		if (ret) {
 			puts("ERROR with allocation of cmdline\n");
 			return ret;
@@ -187,14 +186,13 @@
 static int boot_bd_t_linux(struct bootm_headers *images)
 {
 	ulong of_size = images->ft_len;
-	struct lmb *lmb = &images->lmb;
 	struct bd_info **kbd = &images->kbd;
 
 	int ret = 0;
 
 	if (!of_size) {
 		/* allocate space for kernel copy of board info */
-		ret = boot_get_kbd (lmb, kbd);
+		ret = boot_get_kbd(kbd);
 		if (ret) {
 			puts("ERROR with allocation of kernel bd\n");
 			return ret;
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 13cbaab..bbf62f9 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -142,7 +142,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	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 e298d76..44ac059 100644
--- a/arch/sh/lib/bootm.c
+++ b/arch/sh/lib/bootm.c
@@ -110,7 +110,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	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 2c889bc..114b310 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -267,7 +267,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	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 1de06b7..bdbd6d4 100644
--- a/arch/xtensa/lib/bootm.c
+++ b/arch/xtensa/lib/bootm.c
@@ -206,7 +206,7 @@
 	return ret;
 }
 
-void arch_lmb_reserve(struct lmb *lmb)
+void arch_lmb_reserve(void)
 {
-	arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
+	arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096);
 }