[U-Boot-Users] [PATCH] Add lmb_free

Andy Fleming afleming at freescale.com
Tue May 20 22:18:20 CEST 2008


lmb_free allows us to unreserve some memory so we can use lmb_alloc_base or
lmb_reserve to temporarily reserve some memory.

Signed-off-by: Andy Fleming <afleming at freescale.com>
---
 lib_generic/lmb.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/lib_generic/lmb.c b/lib_generic/lmb.c
index 3b8c805..a34e2d3 100644
--- a/lib_generic/lmb.c
+++ b/lib_generic/lmb.c
@@ -180,6 +180,55 @@ long lmb_add(struct lmb *lmb, ulong base, ulong size)
 	return lmb_add_region(_rgn, base, size);
 }
 
+long lmb_free(struct lmb *lmb, u64 base, u64 size)
+{
+	struct lmb_region *rgn = &(lmb->reserved);
+	u64 rgnbegin, rgnend;
+	u64 end = base + size;
+	int i;
+
+	rgnbegin = rgnend = 0; /* supress gcc warnings */
+
+	/* Find the region where (base, size) belongs to */
+	for (i=0; i < rgn->cnt; i++) {
+		rgnbegin = rgn->region[i].base;
+		rgnend = rgnbegin + rgn->region[i].size;
+
+		if ((rgnbegin <= base) && (end <= rgnend))
+			break;
+	}
+
+	/* Didn't find the region */
+	if (i == rgn->cnt)
+		return -1;
+
+	/* Check to see if we are removing entire region */
+	if ((rgnbegin == base) && (rgnend == end)) {
+		lmb_remove_region(rgn, i);
+		return 0;
+	}
+
+	/* Check to see if region is matching at the front */
+	if (rgnbegin == base) {
+		rgn->region[i].base = end;
+		rgn->region[i].size -= size;
+		return 0;
+	}
+
+	/* Check to see if the region is matching at the end */
+	if (rgnend == end) {
+		rgn->region[i].size -= size;
+		return 0;
+	}
+
+	/*
+	 * We need to split the entry -  adjust the current one to the
+	 * beginging of the hole and add the region after hole.
+	 */
+	rgn->region[i].size = base - rgn->region[i].base;
+	return lmb_add_region(rgn, end, rgnend - end);
+}
+
 long lmb_reserve(struct lmb *lmb, ulong base, ulong size)
 {
 	struct lmb_region *_rgn = &(lmb->reserved);
-- 
1.5.4.GIT





More information about the U-Boot mailing list