Module Name:    src
Committed By:   jmcneill
Date:           Tue Oct 30 21:32:35 UTC 2018

Modified Files:
        src/sys/arch/evbarm/fdt: fdt_machdep.c
Added Files:
        src/sys/arch/evbarm/fdt: fdt_memory.c fdt_memory.h

Log Message:
Replace extent(9) with our own code to deal with adding and reserving
memory ranges.


To generate a diff of this commit:
cvs rdiff -u -r1.48 -r1.49 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/fdt/fdt_memory.c \
    src/sys/arch/evbarm/fdt/fdt_memory.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.48 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.49
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.48	Tue Oct 30 16:41:53 2018
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c	Tue Oct 30 21:32:35 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.48 2018/10/30 16:41:53 skrll Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.49 2018/10/30 21:32:35 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.48 2018/10/30 16:41:53 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.49 2018/10/30 21:32:35 jmcneill Exp $");
 
 #include "opt_machdep.h"
 #include "opt_bootconfig.h"
@@ -55,7 +55,6 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.
 #include <sys/proc.h>
 #include <sys/reboot.h>
 #include <sys/termios.h>
-#include <sys/extent.h>
 #include <sys/bootblock.h>
 #include <sys/disklabel.h>
 #include <sys/vnode.h>
@@ -80,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.
 #include <evbarm/include/autoconf.h>
 #include <evbarm/fdt/machdep.h>
 #include <evbarm/fdt/platform.h>
+#include <evbarm/fdt/fdt_memory.h>
 
 #include <arm/fdt/arm_fdtvar.h>
 
@@ -110,9 +110,6 @@ char *boot_args = NULL;
 u_long uboot_args[4] __attribute__((__section__(".data")));
 const uint8_t *fdt_addr_r __attribute__((__section__(".data")));
 
-static char fdt_memory_ext_storage[EXTENT_FIXED_STORAGE_SIZE(DRAM_BLOCKS)];
-static struct extent *fdt_memory_ext;
-
 static uint64_t initrd_start, initrd_end;
 
 #include <libfdt.h>
@@ -198,16 +195,7 @@ fdt_get_memory(uint64_t *pstart, uint64_
 void
 fdt_add_reserved_memory_range(uint64_t addr, uint64_t size)
 {
-	uint64_t start = addr;
-	uint64_t end = addr + size;
-
-	int error = extent_free(fdt_memory_ext, start,
-	     end - start, EX_NOWAIT);
-	if (error != 0)
-		printf("MEM ERROR: res %" PRIx64 "-%" PRIx64 " failed: %d\n",
-		    start, end, error);
-	else
-		VPRINTF("MEM: res %" PRIx64 "-%" PRIx64 "\n", start, end);
+	fdt_memory_remove_range(addr, size);
 }
 
 /*
@@ -248,6 +236,49 @@ fdt_add_reserved_memory(uint64_t min_add
 	}
 }
 
+static void
+fdt_add_dram_blocks(const struct fdt_memory *m, void *arg)
+{
+	BootConfig *bc = arg;
+
+	VPRINTF("  %lx - %lx\n", m->start, m->end - 1);
+	bc->dram[bc->dramblocks].address = m->start;
+	bc->dram[bc->dramblocks].pages =
+	    (m->end - m->start) / PAGE_SIZE;
+	bc->dramblocks++;
+}
+
+#define MAX_PHYSMEM 64
+static int nfdt_physmem = 0;
+static struct boot_physmem fdt_physmem[MAX_PHYSMEM];
+
+static void
+fdt_add_boot_physmem(const struct fdt_memory *m, void *arg)
+{
+	struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++];
+
+	VPRINTF("  %lx - %lx\n", m->start, m->end - 1);
+
+	KASSERT(nfdt_physmem <= MAX_PHYSMEM);
+
+	bp->bp_start = atop(round_page(m->start));
+	bp->bp_pages = atop(trunc_page(m->end)) - bp->bp_start;
+	bp->bp_freelist = VM_FREELIST_DEFAULT;
+
+#ifdef _LP64
+	if (m->end > 0x100000000)
+		bp->bp_freelist = VM_FREELIST_HIGHMEM;
+#endif
+
+#ifdef PMAP_NEED_ALLOC_POOLPAGE
+	const uint64_t memory_size = *(uint64_t *)arg;
+	if (atop(memory_size) > bp->bp_pages) {
+		arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP;
+		bp->bp_freelist = VM_FREELIST_DIRECTMAP;
+	}
+#endif
+}
+
 /*
  * Define usable memory regions.
  */
@@ -256,12 +287,8 @@ fdt_build_bootconfig(uint64_t mem_start,
 {
 	const int memory = OF_finddevice("/memory");
 	BootConfig *bc = &bootconfig;
-	struct extent_region *er;
 	uint64_t addr, size;
-	int index, error;
-
-	fdt_memory_ext = extent_create("FDT Memory", mem_start, mem_end,
-	    fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), EX_EARLY);
+	int index;
 
 	for (index = 0;
 	     fdtbus_get_reg64(memory, index, &addr, &size) == 0;
@@ -271,19 +298,14 @@ fdt_build_bootconfig(uint64_t mem_start,
 		if (addr + size > mem_end)
 			size = mem_end - addr;
 
-		error = extent_alloc_region(fdt_memory_ext, addr, size,
-		    EX_NOWAIT);
-		if (error != 0)
-			printf("MEM ERROR: add %" PRIx64 "-%" PRIx64 " failed: %d\n",
-			    addr, addr + size, error);
-		VPRINTF("MEM: add %" PRIx64 "-%" PRIx64 "\n", addr, addr + size);
+		fdt_memory_add_range(addr, size);
 	}
 
 	fdt_add_reserved_memory(mem_start, mem_end);
 
 	const uint64_t initrd_size = initrd_end - initrd_start;
 	if (initrd_size > 0)
-		fdt_add_reserved_memory_range(initrd_start, initrd_size);
+		fdt_memory_remove_range(initrd_start, initrd_size);
 
 	const int framebuffer = OF_finddevice("/chosen/framebuffer");
 	if (framebuffer >= 0) {
@@ -296,13 +318,7 @@ fdt_build_bootconfig(uint64_t mem_start,
 
 	VPRINTF("Usable memory:\n");
 	bc->dramblocks = 0;
-	LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
-		VPRINTF("  %lx - %lx\n", er->er_start, er->er_end);
-		bc->dram[bc->dramblocks].address = er->er_start;
-		bc->dram[bc->dramblocks].pages =
-		    (er->er_end - er->er_start) / PAGE_SIZE;
-		bc->dramblocks++;
-	}
+	fdt_memory_foreach(fdt_add_dram_blocks, bc);
 }
 
 static void
@@ -518,34 +534,8 @@ initarm(void *arg)
 
 	parse_mi_bootargs(boot_args);
 
-	#define MAX_PHYSMEM 64
-	static struct boot_physmem fdt_physmem[MAX_PHYSMEM];
-	int nfdt_physmem = 0;
-	struct extent_region *er;
-
-	VPRINTF("Memory regions :\n");
-	LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
-		VPRINTF("  %lx - %lx\n", er->er_start, er->er_end);
-		struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++];
-
-		KASSERT(nfdt_physmem <= MAX_PHYSMEM);
-
-		bp->bp_start = atop(round_page(er->er_start));
-		bp->bp_pages = atop(trunc_page(er->er_end + 1)) - bp->bp_start;
-		bp->bp_freelist = VM_FREELIST_DEFAULT;
-
-#ifdef _LP64
-		if (er->er_end > 0x100000000)
-			bp->bp_freelist = VM_FREELIST_HIGHMEM;
-#endif
-
-#ifdef PMAP_NEED_ALLOC_POOLPAGE
-		if (atop(memory_size) > bp->bp_pages) {
-			arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP;
-			bp->bp_freelist = VM_FREELIST_DIRECTMAP;
-		}
-#endif
-	}
+	VPRINTF("Memory regions:\n");
+	fdt_memory_foreach(fdt_add_boot_physmem, &memory_size);
 
 	u_int sp = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem,
 	     nfdt_physmem);

Added files:

Index: src/sys/arch/evbarm/fdt/fdt_memory.c
diff -u /dev/null src/sys/arch/evbarm/fdt/fdt_memory.c:1.1
--- /dev/null	Tue Oct 30 21:32:35 2018
+++ src/sys/arch/evbarm/fdt/fdt_memory.c	Tue Oct 30 21:32:35 2018
@@ -0,0 +1,169 @@
+/* $NetBSD: fdt_memory.c,v 1.1 2018/10/30 21:32:35 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jared McNeill <jmcne...@invisible.ca>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_bootconfig.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: fdt_memory.c,v 1.1 2018/10/30 21:32:35 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#include <evbarm/fdt/fdt_memory.h>
+
+struct fdt_memory_range {
+	struct fdt_memory               mr_mem;
+	bool                            mr_used;
+	TAILQ_ENTRY(fdt_memory_range)   mr_list;
+};
+
+static TAILQ_HEAD(fdt_memory_rangehead, fdt_memory_range) fdt_memory_ranges =
+    TAILQ_HEAD_INITIALIZER(fdt_memory_ranges);
+
+static struct fdt_memory_range fdt_memory_range_pool[sizeof(struct fdt_memory_range) * DRAM_BLOCKS];
+
+static struct fdt_memory_range *
+fdt_memory_range_alloc(void)
+{
+	for (size_t n = 0; n < DRAM_BLOCKS; n++)
+		if (!fdt_memory_range_pool[n].mr_used) {
+			fdt_memory_range_pool[n].mr_used = true;
+			return &fdt_memory_range_pool[n];
+		}
+
+	printf("%s: no free memory ranges, increase DRAM_BLOCKS!\n", __func__);
+	return NULL;
+}
+
+static void
+fdt_memory_range_free(struct fdt_memory_range *mr)
+{
+	mr->mr_used = false;
+}
+
+void
+fdt_memory_add_range(uint64_t start, uint64_t size)
+{
+	struct fdt_memory_range *mr, *prev, *cur, *tmp;
+	bool inserted = false;
+
+	mr = fdt_memory_range_alloc();
+	if (mr == NULL)
+		return;
+
+	mr->mr_mem.start = start;
+	mr->mr_mem.end = start + size;
+
+	/*
+	 * Add the new range to the list of sorted ranges.
+	 */
+	TAILQ_FOREACH(cur, &fdt_memory_ranges, mr_list)
+		if (mr->mr_mem.start <= cur->mr_mem.start) {
+			TAILQ_INSERT_BEFORE(cur, mr, mr_list);
+			inserted = true;
+			break;
+		}
+	if (!inserted)
+		TAILQ_INSERT_TAIL(&fdt_memory_ranges, mr, mr_list);
+
+	/*
+	 * Remove overlaps.
+	 */
+	TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) {
+		prev = TAILQ_PREV(mr, fdt_memory_rangehead, mr_list);
+		if (prev && prev->mr_mem.end > mr->mr_mem.start) {
+			mr->mr_mem.start = prev->mr_mem.end;
+			if (mr->mr_mem.start >= mr->mr_mem.end) {
+				TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list);
+				fdt_memory_range_free(mr);
+			}
+		}
+	}
+
+	/*
+	 * Combine adjacent ranges.
+	 */
+	TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) {
+		prev = TAILQ_PREV(mr, fdt_memory_rangehead, mr_list);
+		if (prev && prev->mr_mem.end == mr->mr_mem.start) {
+			prev->mr_mem.end = mr->mr_mem.end;
+			TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list);
+			fdt_memory_range_free(mr);
+		}
+	}
+}
+
+void
+fdt_memory_remove_range(uint64_t start, uint64_t size)
+{
+	struct fdt_memory_range *mr, *next, *tmp;
+	const uint64_t end = start + size;
+
+	TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) {
+		if (start <= mr->mr_mem.start && end >= mr->mr_mem.end) {
+			/*
+			 * Removed range completely covers this range,
+			 * just remove it.
+			 */
+			TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list);
+			fdt_memory_range_free(mr);
+		} else if (start > mr->mr_mem.start && end < mr->mr_mem.end) {
+			/*
+			 * Removed range is completely contained by this range,
+			 * split it.
+			 */
+			next = fdt_memory_range_alloc();
+			if (next == NULL)
+				panic("fdt_memory_remove_range");
+			next->mr_mem.start = end;
+			next->mr_mem.end = mr->mr_mem.end;
+			mr->mr_mem.end = start;
+			TAILQ_INSERT_AFTER(&fdt_memory_ranges, mr, next, mr_list);
+		} else {
+			/*
+			 * Partial overlap.
+			 */
+			if (start >= mr->mr_mem.start && start < mr->mr_mem.end)
+				mr->mr_mem.end = start;
+			if (end < mr->mr_mem.end && end > mr->mr_mem.start)
+				mr->mr_mem.start = end;
+		}
+	}
+}
+
+void
+fdt_memory_foreach(void (*fn)(const struct fdt_memory *, void *), void *arg)
+{
+	struct fdt_memory_range *mr;
+
+	TAILQ_FOREACH(mr, &fdt_memory_ranges, mr_list)
+		fn(&mr->mr_mem, arg);
+}
Index: src/sys/arch/evbarm/fdt/fdt_memory.h
diff -u /dev/null src/sys/arch/evbarm/fdt/fdt_memory.h:1.1
--- /dev/null	Tue Oct 30 21:32:35 2018
+++ src/sys/arch/evbarm/fdt/fdt_memory.h	Tue Oct 30 21:32:35 2018
@@ -0,0 +1,44 @@
+/* $NetBSD: fdt_memory.h,v 1.1 2018/10/30 21:32:35 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jared McNeill <jmcne...@invisible.ca>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _EVBARM_FDT_FDT_MEMORY_H
+#define _EVBARM_FDT_FDT_MEMORY_H
+
+struct fdt_memory {
+	uint64_t	start;
+	uint64_t	end;
+};
+
+void	fdt_memory_add_range(uint64_t, uint64_t);
+void	fdt_memory_remove_range(uint64_t, uint64_t);
+void	fdt_memory_foreach(void (*)(const struct fdt_memory *, void *), void *);
+
+#endif /* !_EVBARM_FDT_FDT_MEMORY_H */

Reply via email to