diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-03-14 16:14:02 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-04-04 07:44:26 +0200 |
commit | d4ff9c40baf3cf64565c423d6f7622f27ec48a84 (patch) | |
tree | 5d11a4d0d51da1ed725392dc23f2a17d84a238aa /common | |
parent | 41dd040d2cc4d248a63f316f90118560437a4abc (diff) | |
download | barebox-d4ff9c40baf3cf64565c423d6f7622f27ec48a84.tar.gz barebox-d4ff9c40baf3cf64565c423d6f7622f27ec48a84.tar.xz |
common: Add functions to find free RAM
The bootm code needs to put the Kernel image and initrd into free
RAM. Add some functions to find free RAM chunks to help this code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r-- | common/memory.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/common/memory.c b/common/memory.c index ff5bdc14e2..00fa7c50ff 100644 --- a/common/memory.c +++ b/common/memory.c @@ -171,6 +171,57 @@ int release_sdram_region(struct resource *res) return release_region(res); } +void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart, + resource_size_t *retend) +{ + resource_size_t freeptr, size, maxfree = 0; + struct resource *last, *child; + + if (list_empty(&bank->res->children)) { + /* No children - return the whole bank */ + *retstart = bank->res->start; + *retend = bank->res->end; + return; + } + + freeptr = bank->res->start; + + list_for_each_entry(child, &bank->res->children, sibling) { + /* Check gaps between child resources */ + size = child->start - freeptr; + if (size > maxfree) { + *retstart = freeptr; + *retend = child->start - 1; + maxfree = size; + } + freeptr = child->start + resource_size(child); + } + + last = list_last_entry(&bank->res->children, struct resource, sibling); + + /* Check gap between last child and end of memory bank */ + freeptr = last->start + resource_size(last); + size = bank->res->start + resource_size(bank->res) - freeptr; + + if (size > maxfree) { + *retstart = freeptr; + *retend = bank->res->end; + } +} + +int memory_bank_first_find_space(resource_size_t *retstart, + resource_size_t *retend) +{ + struct memory_bank *bank; + + for_each_memory_bank(bank) { + memory_bank_find_space(bank, retstart, retend); + return 0; + } + + return -ENOENT; +} + #ifdef CONFIG_OFTREE static int of_memory_fixup(struct device_node *node, void *unused) |