summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-03-14 16:14:02 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-04-04 07:44:26 +0200
commitd4ff9c40baf3cf64565c423d6f7622f27ec48a84 (patch)
tree5d11a4d0d51da1ed725392dc23f2a17d84a238aa /common
parent41dd040d2cc4d248a63f316f90118560437a4abc (diff)
downloadbarebox-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.c51
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)