diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/memrange.h | 29 | ||||
-rw-r--r-- | src/lib/memrange.c | 26 |
2 files changed, 40 insertions, 15 deletions
diff --git a/src/include/memrange.h b/src/include/memrange.h index 7f42aa2b0b..0d20236d61 100644 --- a/src/include/memrange.h +++ b/src/include/memrange.h @@ -24,6 +24,8 @@ struct memranges { /* coreboot doesn't have a free() function. Therefore, keep a cache of * free'd entries. */ struct range_entry *free_list; + /* Alignment for base and end addresses of the range. (Must be power of 2). */ + size_t align; }; /* Each region within a memranges structure is represented by a @@ -86,17 +88,32 @@ static inline void range_entry_update_tag(struct range_entry *r, #define memranges_each_entry(r, ranges) \ for (r = (ranges)->entries; r != NULL; r = r->next) + /* Initialize memranges structure providing an optional array of range_entry - * to use as the free list. */ -void memranges_init_empty(struct memranges *ranges, struct range_entry *free, - size_t num_free); + * to use as the free list. Additionally, it accepts an align parameter that + * determines the alignment of addresses. (Alignment must be a power of 2). */ +void memranges_init_empty_with_alignment(struct memranges *ranges, + struct range_entry *free, + size_t num_free, size_t align); /* Initialize and fill a memranges structure according to the * mask and match type for all memory resources. Tag each entry with the - * specified type. */ -void memranges_init(struct memranges *ranges, + * specified type. Additionally, it accepts an align parameter that + * determines the alignment of addresses. (Alignment must be a power of 2). */ +void memranges_init_with_alignment(struct memranges *ranges, unsigned long mask, unsigned long match, - unsigned long tag); + unsigned long tag, size_t align); + +/* Initialize memranges structure providing an optional array of range_entry + * to use as the free list. Addresses are default aligned to 4KiB. */ +#define memranges_init_empty(__ranges, __free, __num_free) \ + memranges_init_empty_with_alignment(__ranges, __free, __num_free, 4 * KiB) + +/* Initialize and fill a memranges structure according to the + * mask and match type for all memory resources. Tag each entry with the + * specified type. Addresses are default aligned to 4KiB. */ +#define memranges_init(__ranges, __mask, __match, __tag) \ + memranges_init_with_alignment(__ranges, __mask, __match, __tag, 4 * KiB) /* Clone a memrange. The new memrange has the same entries as the old one. */ void memranges_clone(struct memranges *newranges, struct memranges *oldranges); 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 <assert.h> #include <stdlib.h> +#include <commonlib/helpers.h> #include <console/console.h> #include <memrange.h> @@ -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) { |