aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/memrange.h29
-rw-r--r--src/lib/memrange.c26
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) {