Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41418 )
Change subject: memrange: Add helper for stealing memory from the last range in the list ......................................................................
memrange: Add helper for stealing memory from the last range in the list
This change adds a helper fucntion memranges_steal_last() that allows the caller to request memory to be stolen from the last range in the list. Memory is stolen from the start of the last range and matches the constraints (limit, align, tag, size) provided by the caller.
The current helper functin memranges_steal() defaults to always returning stolen memory from the first available range in the list.
Additionally, this change updates the internal function memranges_find_entry() to handle stealing from first and last entries as requested by the caller.
Change-Id: I70c07e587597b44306857f0e52eb47b330ca3b1b Signed-off-by: Furquan Shaikh furquan@google.com --- M src/include/memrange.h M src/lib/memrange.c 2 files changed, 59 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/41418/1
diff --git a/src/include/memrange.h b/src/include/memrange.h index 2b8c00e..4b64e1a 100644 --- a/src/include/memrange.h +++ b/src/include/memrange.h @@ -160,7 +160,8 @@ struct range_entry *memranges_next_entry(struct memranges *ranges, const struct range_entry *r);
-/* Steals memory from the available list in given ranges as per the constraints: +/* Steals memory from the first available entry in the list of given ranges as per the + * constraints: * limit = Upper bound for the memory range to steal (Inclusive). * size = Requested size for the stolen memory. * align = Required alignment(log 2) for the starting address of the stolen memory. @@ -172,4 +173,18 @@ bool memranges_steal(struct memranges *ranges, resource_t limit, resource_t size, unsigned char align, unsigned long tag, resource_t *stolen_base);
+ +/* Steals memory from the last available entry in the list of given ranges as per the + * constraints: + * limit = Upper bound for the memory range to steal (Inclusive). + * size = Requested size for the stolen memory. + * align = Required alignment(log 2) for the starting address of the stolen memory. + * tag = Use a range that matches the given tag. + * + * If the constraints can be satisfied, this function creates a hole in the memrange, + * writes the base address of that hole to stolen_base and returns true. Otherwise it returns + * false. */ +bool memranges_steal_last(struct memranges *ranges, resource_t limit, resource_t size, + unsigned char align, unsigned long tag, resource_t *stolen_base); + #endif /* MEMRANGE_H_ */ diff --git a/src/lib/memrange.c b/src/lib/memrange.c index 39f502c..4b13b00 100644 --- a/src/lib/memrange.c +++ b/src/lib/memrange.c @@ -376,17 +376,27 @@ return r->next; }
+enum { + STEAL_FIRST_AVAILABLE, + STEAL_LAST_AVAILABLE, +} + /* Find a range entry that satisfies the given constraints to fit a hole that matches the - * required alignment, is big enough, does not exceed the limit and has a matching tag. */ + * required alignment, is big enough, does not exceed the limit and has a matching tag. + * Depending upon the value of "steal_from", this function either returns the first range entry + * that satisfies the constraints (STEAL_FIRST_AVAILABLE) or the last range entry that + * satisfies the constrains (STEAL_LAST_AVAILABLE). */ static const struct range_entry *memranges_find_entry(struct memranges *ranges, resource_t limit, resource_t size, - unsigned char align, unsigned long tag) + unsigned char align, unsigned long tag, + int steal_from) { const struct range_entry *r; + const struct range_entry *last_entry = NULL; resource_t base, end;
if (size == 0) - return NULL; + return false;
memranges_each_entry(r, ranges) {
@@ -407,17 +417,27 @@ if (end > limit) break;
- return r; + last_entry = r; + + /* + * If caller wants to steal from the first available range, then break and + * return the found entry. + */ + if (steal_from == STEAL_FIRST_AVAILABLE) + break; }
- return NULL; + return last_entry; }
-bool memranges_steal(struct memranges *ranges, resource_t limit, resource_t size, - unsigned char align, unsigned long tag, resource_t *stolen_base) +static bool __memranges_steal(struct memranges *ranges, resource_t limit, resource_t size, + unsigned char align, unsigned long tag, resource_t *stolen_base, + int steal_from) { resource_t base; - const struct range_entry *r = memranges_find_entry(ranges, limit, size, align, tag); + const struct range_entry *r; + + r = memranges_find_entry(ranges, limit, size, align, tag, steal_from);
if (r == NULL) return false; @@ -428,4 +448,19 @@ *stolen_base = base;
return true; + +} + +bool memranges_steal(struct memranges *ranges, resource_t limit, resource_t size, + unsigned char align, unsigned long tag, resource_t *stolen_base) +{ + return __memranges_steal(ranges, limit, size, align, tag, stolen_base, + STEAL_FIRST_AVAILABLE); +} + +bool memranges_steal_last(struct memranges *ranges, resource_t limit, resource_t size, + unsigned char align, unsigned long tag, resource_t *stolen_base) +{ + return __memranges_steal(ranges, limit, size, align, tag, stolen_base, + STEAL_LAST_AVAILABLE); }