From 1429092d02e8157c8e6c26849e0c8aa096da9c0c Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Wed, 11 Mar 2020 14:35:35 -0700 Subject: memrange: Enable memranges to support different alignments This change enables memranges library to support addresses with different alignments. Before this change, memranges library supported aligning addresses to 4KiB only. Though this works for most cases, it might not be the right alignment for every use case. Example: There are some resource allocator changes coming up that require a different alignment when handling the range list. This change adds a align parameter to struct memranges that determines the alignment of all range lists in that memrange. In order to continue supporting current users of memranges, default alignment is maintained as 4KiB. BUG=b:149186922 Signed-off-by: Furquan Shaikh Change-Id: I1da0743ff89da734c9a0972e3c56d9f512b3d1e8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/39483 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/lib/memrange.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/lib') diff --git a/src/lib/memrange.c b/src/lib/memrange.c index 79a1b0ee49..21fff003a1 100644 --- a/src/lib/memrange.c +++ b/src/lib/memrange.c @@ -12,7 +12,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +#include #include +#include #include #include @@ -231,9 +234,9 @@ static void do_action(struct memranges *ranges, /* The addresses are aligned to 4096 bytes: the begin address is * aligned down while the end address is aligned up to be conservative * about the full range covered. */ - begin = ALIGN_DOWN(base, 4096); + begin = ALIGN_DOWN(base, ranges->align); end = begin + size + (base - begin); - end = ALIGN_UP(end, 4096) - 1; + end = ALIGN_UP(end, ranges->align) - 1; action(ranges, begin, end, tag); } @@ -290,23 +293,28 @@ void memranges_add_resources(struct memranges *ranges, memranges_add_resources_filter(ranges, mask, match, tag, NULL); } -void memranges_init_empty(struct memranges *ranges, struct range_entry *to_free, - size_t num_free) +void memranges_init_empty_with_alignment(struct memranges *ranges, + struct range_entry *to_free, + size_t num_free, size_t align) { size_t i; + /* Alignment must be a power of 2. */ + assert(IS_POWER_OF_2(align)); + ranges->entries = NULL; ranges->free_list = NULL; + ranges->align = align; for (i = 0; i < num_free; i++) range_entry_link(&ranges->free_list, &to_free[i]); } -void memranges_init(struct memranges *ranges, - unsigned long mask, unsigned long match, - unsigned long tag) +void memranges_init_with_alignment(struct memranges *ranges, + unsigned long mask, unsigned long match, + unsigned long tag, size_t align) { - memranges_init_empty(ranges, NULL, 0); + memranges_init_empty_with_alignment(ranges, NULL, 0, align); memranges_add_resources(ranges, mask, match, tag); } @@ -316,7 +324,7 @@ void memranges_clone(struct memranges *newranges, struct memranges *oldranges) struct range_entry *r, *cur; struct range_entry **prev_ptr; - memranges_init_empty(newranges, NULL, 0); + memranges_init_empty_with_alignment(newranges, NULL, 0, oldranges->align); prev_ptr = &newranges->entries; memranges_each_entry(r, oldranges) { -- cgit v1.2.3