[coreboot-gerrit] Patch set updated for coreboot: lib/memrange: Add utilities to identify overlapping regions

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Wed Jan 13 19:48:50 CET 2016


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/12915

-gerrit

commit 7ec8aabfb5a11b4b54e72461e5a23e8b04f8c13d
Author: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
Date:   Tue Jan 12 14:26:31 2016 -0800

    lib/memrange: Add utilities to identify overlapping regions
    
    Add utilities to check if memory regions overlap, and merge
    overlapping regions into a larger region. This also provides a utility
    to check if a memory range overlaps the current stage. This is useful,
    for example, when copying or decompressing cbfs files to memory.
    
    Change-Id: Iedb927da01ead6d6a5c520cc9b91460dc75286e3
    Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
---
 src/include/memrange.h | 29 +++++++++++++++++++++++++++++
 src/lib/Makefile.inc   |  3 +++
 src/lib/memrange.c     | 30 ++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+)

diff --git a/src/include/memrange.h b/src/include/memrange.h
index 9e8c704..fe11f0e 100644
--- a/src/include/memrange.h
+++ b/src/include/memrange.h
@@ -16,6 +16,7 @@
 #define MEMRANGE_H_
 
 #include <device/resource.h>
+#include <stdint.h>
 
 /* A memranges structure consists of a list of range_entry(s). The structure
  * is exposed so that a memranges can be used on the stack if needed. */
@@ -63,6 +64,34 @@ static inline void range_entry_update_tag(struct range_entry *r,
 	r->tag = new_tag;
 }
 
+/* Create range_entry struct given start and end addresses */
+static inline struct range_entry memrange_from_start_end(resource_t start,
+							 resource_t end)
+{
+	struct range_entry memrange = {
+		.begin = start,
+		.end = end,
+		.tag = 0,
+		.next = NULL,
+	};
+	return memrange;
+}
+
+/* Create range_entry struct given start address and size */
+static inline struct range_entry memrange_from_start_size(resource_t start,
+							  size_t size)
+{
+	return memrange_from_start_end(start, start + size);
+}
+
+/* Returns true if two memory regions overlap, or one contains the other */
+bool memranges_overlap(const struct range_entry *a,
+		       const struct range_entry *b);
+/* Merge two regions into one. Assumes regions overlap. Region b is disabled */
+void memranges_merge(struct range_entry *a, struct range_entry *b);
+/* Returns true if a memory region overlaps the current program */
+bool memrange_overlaps_program(const struct range_entry *region);
+
 /* Iterate over each entry in a memranges structure. Ranges cannot
  * be deleted while processing each entry as the list cannot be safely
  * traversed after such an operation.
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 724391f..6bb49b6 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -25,6 +25,7 @@ bootblock-y += cbfs.c
 bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
 bootblock-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
 bootblock-y += libgcc.c
+bootblock-y += memrange.c
 bootblock-$(CONFIG_GENERIC_UDELAY) += timer.c
 
 ifeq ($(CONFIG_EARLY_CBMEM_INIT),y)
@@ -46,6 +47,7 @@ verstage-y += halt.c
 verstage-y += fmap.c
 verstage-y += libgcc.c
 verstage-y += memcmp.c
+verstage-y += memrange.c
 verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
 verstage-y += boot_device.c
 verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
@@ -64,6 +66,7 @@ romstage-y += prog_loaders.c
 romstage-y += prog_ops.c
 romstage-y += memchr.c
 romstage-y += memcmp.c
+romstage-y += memrange.c
 $(foreach arch,$(ARCH_SUPPORTED),\
 	    $(eval rmodules_$(arch)-y += memcmp.c) \
 	    $(eval rmodules_$(arch)-y += rmodule.ld))
diff --git a/src/lib/memrange.c b/src/lib/memrange.c
index b2839d0..6d505c0 100644
--- a/src/lib/memrange.c
+++ b/src/lib/memrange.c
@@ -12,14 +12,44 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include <lib.h>
 #include <stdlib.h>
 #include <console/console.h>
 #include <memrange.h>
+#include <symbols.h>
 
 /* Coreboot doesn't have a free() function. Therefore, keep a cache of
  * free'd entries.  */
 static struct range_entry *free_list;
 
+bool memranges_overlap(const struct range_entry *a, const struct range_entry *b)
+{
+	if ((a->end < b->begin) || (b->end < a->begin))
+		return false;
+
+	return true;
+}
+
+void memranges_merge(struct range_entry *a, struct range_entry *b)
+{
+	/* Merge second region into first */
+	a->begin = MIN(a->begin, b->begin);
+	a->end = MAX(a->end, b->end);
+
+	/* Disable the second region */
+	b->begin = b->end = 0;
+}
+
+bool memrange_overlaps_program(const struct range_entry *region)
+{
+	const struct range_entry program = memrange_from_start_end(
+		(resource_t)(uintptr_t)&_program,
+		(resource_t)(uintptr_t)&_eprogram
+	);
+
+	return memranges_overlap(region, &program);
+}
+
 static inline void range_entry_link(struct range_entry **prev_ptr,
                                     struct range_entry *r)
 {



More information about the coreboot-gerrit mailing list