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()]
This commit is contained in:
@@ -68,12 +68,11 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
|
||||
uint64_t size, enum lmb_flags flags)
|
||||
static void boot_fdt_reserve_region(u64 addr, u64 size, enum lmb_flags flags)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = lmb_reserve_flags(lmb, addr, size, flags);
|
||||
ret = lmb_reserve_flags(addr, size, flags);
|
||||
if (ret >= 0) {
|
||||
debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
|
||||
(unsigned long long)addr,
|
||||
@@ -89,14 +88,13 @@ static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
|
||||
/**
|
||||
* boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
|
||||
* sections as unusable
|
||||
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||
* @fdt_blob: pointer to fdt blob base address
|
||||
*
|
||||
* Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
|
||||
* Adding the memreserve regions prevents u-boot from using them to store the
|
||||
* initrd or the fdt blob.
|
||||
*/
|
||||
void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||
void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
|
||||
{
|
||||
uint64_t addr, size;
|
||||
int i, total, ret;
|
||||
@@ -112,7 +110,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||
for (i = 0; i < total; i++) {
|
||||
if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
|
||||
continue;
|
||||
boot_fdt_reserve_region(lmb, addr, size, LMB_NONE);
|
||||
boot_fdt_reserve_region(addr, size, LMB_NONE);
|
||||
}
|
||||
|
||||
/* process reserved-memory */
|
||||
@@ -130,7 +128,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||
flags = LMB_NOMAP;
|
||||
addr = res.start;
|
||||
size = res.end - res.start + 1;
|
||||
boot_fdt_reserve_region(lmb, addr, size, flags);
|
||||
boot_fdt_reserve_region(addr, size, flags);
|
||||
}
|
||||
|
||||
subnode = fdt_next_subnode(fdt_blob, subnode);
|
||||
@@ -140,7 +138,6 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||
|
||||
/**
|
||||
* boot_relocate_fdt - relocate flat device tree
|
||||
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||
* @of_flat_tree: pointer to a char* variable, will hold fdt start address
|
||||
* @of_size: pointer to a ulong variable, will hold fdt length
|
||||
*
|
||||
@@ -155,7 +152,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||
* 0 - success
|
||||
* 1 - failure
|
||||
*/
|
||||
int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
|
||||
int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
|
||||
{
|
||||
u64 start, size, usable, addr, low, mapsize;
|
||||
void *fdt_blob = *of_flat_tree;
|
||||
@@ -187,18 +184,17 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
|
||||
if (desired_addr == ~0UL) {
|
||||
/* All ones means use fdt in place */
|
||||
of_start = fdt_blob;
|
||||
lmb_reserve(lmb, map_to_sysmem(of_start), of_len);
|
||||
lmb_reserve(map_to_sysmem(of_start), of_len);
|
||||
disable_relocation = 1;
|
||||
} else if (desired_addr) {
|
||||
addr = lmb_alloc_base(lmb, of_len, 0x1000,
|
||||
desired_addr);
|
||||
addr = lmb_alloc_base(of_len, 0x1000, desired_addr);
|
||||
of_start = map_sysmem(addr, of_len);
|
||||
if (of_start == NULL) {
|
||||
puts("Failed using fdt_high value for Device Tree");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
addr = lmb_alloc(lmb, of_len, 0x1000);
|
||||
addr = lmb_alloc(of_len, 0x1000);
|
||||
of_start = map_sysmem(addr, of_len);
|
||||
}
|
||||
} else {
|
||||
@@ -220,7 +216,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
|
||||
* for LMB allocation.
|
||||
*/
|
||||
usable = min(start + size, low + mapsize);
|
||||
addr = lmb_alloc_base(lmb, of_len, 0x1000, usable);
|
||||
addr = lmb_alloc_base(of_len, 0x1000, usable);
|
||||
of_start = map_sysmem(addr, of_len);
|
||||
/* Allocation succeeded, use this block. */
|
||||
if (of_start != NULL)
|
||||
@@ -569,8 +565,7 @@ __weak int arch_fixup_fdt(void *blob)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int image_setup_libfdt(struct bootm_headers *images, void *blob,
|
||||
struct lmb *lmb)
|
||||
int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
|
||||
{
|
||||
ulong *initrd_start = &images->initrd_start;
|
||||
ulong *initrd_end = &images->initrd_end;
|
||||
@@ -670,8 +665,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob,
|
||||
}
|
||||
|
||||
/* Delete the old LMB reservation */
|
||||
if (lmb)
|
||||
lmb_free(lmb, map_to_sysmem(blob), fdt_totalsize(blob));
|
||||
if (CONFIG_IS_ENABLED(LMB) && lmb)
|
||||
lmb_free(map_to_sysmem(blob), fdt_totalsize(blob));
|
||||
|
||||
ret = fdt_shrink_to_minimum(blob, 0);
|
||||
if (ret < 0)
|
||||
@@ -679,8 +674,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob,
|
||||
of_size = ret;
|
||||
|
||||
/* Create a new LMB reservation */
|
||||
if (lmb)
|
||||
lmb_reserve(lmb, map_to_sysmem(blob), of_size);
|
||||
if (CONFIG_IS_ENABLED(LMB) && lmb)
|
||||
lmb_reserve(map_to_sysmem(blob), of_size);
|
||||
|
||||
#if defined(CONFIG_ARCH_KEYSTONE)
|
||||
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
|
||||
|
||||
Reference in New Issue
Block a user