Skip to content

Commit

Permalink
lmb: make LMB memory map persistent and global
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Simon Glass <[email protected]>
[sjg: Optimise the logic to add a region in lmb_add_region_flags()]
  • Loading branch information
Sughosh Ganu authored and trini committed Sep 3, 2024
1 parent a368850 commit ed17a33
Show file tree
Hide file tree
Showing 39 changed files with 714 additions and 746 deletions.
4 changes: 2 additions & 2 deletions arch/arc/lib/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ static ulong get_sp(void)
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);
}
4 changes: 2 additions & 2 deletions arch/arm/lib/stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static ulong get_sp(void)
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);
}
17 changes: 8 additions & 9 deletions arch/arm/mach-apple/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,23 +773,22 @@ u64 get_page_table_size(void)

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");
Expand Down
17 changes: 8 additions & 9 deletions arch/arm/mach-snapdragon/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,24 +275,23 @@ void __weak qcom_late_init(void)

#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__);
Expand Down
8 changes: 3 additions & 5 deletions arch/arm/mach-stm32mp/dram_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
{
phys_size_t size;
phys_addr_t reg;
struct lmb lmb;

if (!total_size)
return gd->ram_top;
Expand All @@ -59,12 +58,11 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
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;
Expand Down
6 changes: 2 additions & 4 deletions arch/arm/mach-stm32mp/stm32mp1/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -80,7 +78,7 @@ void dram_bank_mmu_setup(int bank)
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);
}
Expand Down Expand Up @@ -144,7 +142,7 @@ int mach_cpu_init(void)
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 */

Expand Down
7 changes: 3 additions & 4 deletions arch/m68k/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ DECLARE_GLOBAL_DATA_PTR;
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)
Expand All @@ -41,7 +41,6 @@ int do_bootm_linux(int flag, struct bootm_info *bmi)
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
Expand All @@ -53,7 +52,7 @@ int do_bootm_linux(int flag, struct bootm_info *bmi)
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;
Expand Down
4 changes: 2 additions & 2 deletions arch/microblaze/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ static ulong get_sp(void)
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)
Expand Down
11 changes: 5 additions & 6 deletions arch/mips/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ static ulong arch_get_sp(void)
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)
Expand Down Expand Up @@ -225,9 +225,8 @@ static int boot_reloc_fdt(struct bootm_headers *images)
}

#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
Expand All @@ -248,7 +247,7 @@ static int boot_setup_fdt(struct bootm_headers *images)
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)
Expand Down
4 changes: 2 additions & 2 deletions arch/nios2/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static ulong get_sp(void)
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);
}
4 changes: 2 additions & 2 deletions arch/powerpc/cpu/mpc85xx/mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,11 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
}
#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)
Expand Down
4 changes: 1 addition & 3 deletions arch/powerpc/include/asm/mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
14 changes: 6 additions & 8 deletions arch/powerpc/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ static void boot_jump_linux(struct bootm_headers *images)
return;
}

void arch_lmb_reserve(struct lmb *lmb)
void arch_lmb_reserve(void)
{
phys_size_t bootm_size;
ulong size, bootmap_base;
Expand All @@ -139,13 +139,13 @@ void arch_lmb_reserve(struct lmb *lmb)
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;
Expand All @@ -166,15 +166,14 @@ static void boot_prep_linux(struct bootm_headers *images)
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;

int ret = 0;

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;
Expand All @@ -187,14 +186,13 @@ static int boot_cmdline_linux(struct bootm_headers *images)
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;
Expand Down
4 changes: 2 additions & 2 deletions arch/riscv/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static ulong get_sp(void)
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);
}
4 changes: 2 additions & 2 deletions arch/sh/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ static ulong get_sp(void)
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);
}
4 changes: 2 additions & 2 deletions arch/x86/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static ulong get_sp(void)
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);
}
4 changes: 2 additions & 2 deletions arch/xtensa/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static ulong get_sp(void)
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);
}
8 changes: 3 additions & 5 deletions board/xilinx/common/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
{
phys_size_t size;
phys_addr_t reg;
struct lmb lmb;

if (!total_size)
return gd->ram_top;
Expand All @@ -684,11 +683,10 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);

/* found enough not-reserved memory to relocated U-Boot */
lmb_init(&lmb);
lmb_add(&lmb, gd->ram_base, gd->ram_size);
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
lmb_add(gd->ram_base, gd->ram_size);
boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob);
size = ALIGN(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;
Expand Down
Loading

0 comments on commit ed17a33

Please sign in to comment.