Module Name: src
Committed By: skrll
Date: Sat Dec 12 09:27:32 UTC 2020
Modified Files:
src/sys/arch/aarch64/aarch64: aarch64_machdep.c
src/sys/arch/arm/arm32: arm32_kvminit.c
src/sys/arch/evbarm/conf: files.fdt
src/sys/arch/evbarm/fdt: fdt_machdep.c platform.h
src/sys/dev/fdt: files.fdt
Added Files:
src/sys/dev/fdt: fdt_memory.c fdt_memory.h
Removed Files:
src/sys/arch/evbarm/fdt: fdt_memory.c fdt_memory.h
Log Message:
Move evbarm/fdt/fdt_memory.[ch] to sys/dev/fdt and simplify the api and
some operations. This allows other architectures to use it.
To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.56 src/sys/arch/aarch64/aarch64/aarch64_machdep.c
cvs rdiff -u -r1.66 -r1.67 src/sys/arch/arm/arm32/arm32_kvminit.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbarm/conf/files.fdt
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r1.4 -r0 src/sys/arch/evbarm/fdt/fdt_memory.c
cvs rdiff -u -r1.1 -r0 src/sys/arch/evbarm/fdt/fdt_memory.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/fdt/platform.h
cvs rdiff -u -r0 -r1.1 src/sys/dev/fdt/fdt_memory.c \
src/sys/dev/fdt/fdt_memory.h
cvs rdiff -u -r1.56 -r1.57 src/sys/dev/fdt/files.fdt
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/aarch64/aarch64/aarch64_machdep.c
diff -u src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.55 src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.56
--- src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.55 Wed Dec 9 08:51:05 2020
+++ src/sys/arch/aarch64/aarch64/aarch64_machdep.c Sat Dec 12 09:27:31 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.55 2020/12/09 08:51:05 skrll Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.56 2020/12/12 09:27:31 skrll Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.55 2020/12/09 08:51:05 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.56 2020/12/12 09:27:31 skrll Exp $");
#include "opt_arm_debug.h"
#include "opt_cpuoptions.h"
@@ -72,8 +72,8 @@ __KERNEL_RCSID(1, "$NetBSD: aarch64_mach
#include <aarch64/vmparam.h>
#include <aarch64/kcore.h>
-#include <arch/evbarm/fdt/platform.h>
#include <arm/fdt/arm_fdtvar.h>
+#include <dev/fdt/fdt_memory.h>
#ifdef VERBOSE_INIT_ARM
#define VPRINTF(...) printf(__VA_ARGS__)
@@ -193,7 +193,7 @@ cpu_kernel_vm_init(uint64_t memory_start
VPRINTF("%s: kernel phys start %lx end %lx+%lx\n", __func__,
kernstart_phys, kernend_phys, kernend_extra);
- fdt_add_reserved_memory_range(kernstart_phys,
+ fdt_memory_remove_range(kernstart_phys,
kernend_phys - kernstart_phys + kernend_extra);
}
Index: src/sys/arch/arm/arm32/arm32_kvminit.c
diff -u src/sys/arch/arm/arm32/arm32_kvminit.c:1.66 src/sys/arch/arm/arm32/arm32_kvminit.c:1.67
--- src/sys/arch/arm/arm32/arm32_kvminit.c:1.66 Fri Oct 30 18:54:36 2020
+++ src/sys/arch/arm/arm32/arm32_kvminit.c Sat Dec 12 09:27:31 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_kvminit.c,v 1.66 2020/10/30 18:54:36 skrll Exp $ */
+/* $NetBSD: arm32_kvminit.c,v 1.67 2020/12/12 09:27:31 skrll Exp $ */
/*
* Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved.
@@ -127,7 +127,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.66 2020/10/30 18:54:36 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.67 2020/12/12 09:27:31 skrll Exp $");
#include <sys/param.h>
@@ -150,6 +150,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_kvmini
#if defined(FDT)
#include <arch/evbarm/fdt/platform.h>
#include <arm/fdt/arm_fdtvar.h>
+#include <dev/fdt/fdt_memory.h>
#endif
#ifdef MULTIPROCESSOR
@@ -251,7 +252,7 @@ arm32_bootmem_init(paddr_t memstart, psi
bmi->bmi_kernelend = kernelend;
#if defined(FDT)
- fdt_add_reserved_memory_range(bmi->bmi_kernelstart,
+ fdt_memory_remove_range(bmi->bmi_kernelstart,
bmi->bmi_kernelend - bmi->bmi_kernelstart);
#endif
@@ -400,7 +401,7 @@ valloc_pages(struct bootmem_info *bmi, p
KASSERT((armreg_ttbr_read() & ~(L1_TABLE_SIZE - 1)) != free_pv->pv_pa);
#if defined(FDT)
- fdt_add_reserved_memory_range(free_pv->pv_pa, nbytes);
+ fdt_memory_remove_range(free_pv->pv_pa, nbytes);
#endif
pv->pv_pa = free_pv->pv_pa;
pv->pv_va = free_pv->pv_va;
Index: src/sys/arch/evbarm/conf/files.fdt
diff -u src/sys/arch/evbarm/conf/files.fdt:1.6 src/sys/arch/evbarm/conf/files.fdt:1.7
--- src/sys/arch/evbarm/conf/files.fdt:1.6 Thu Feb 20 01:35:55 2020
+++ src/sys/arch/evbarm/conf/files.fdt Sat Dec 12 09:27:31 2020
@@ -1,10 +1,9 @@
-# $NetBSD: files.fdt,v 1.6 2020/02/20 01:35:55 jmcneill Exp $
+# $NetBSD: files.fdt,v 1.7 2020/12/12 09:27:31 skrll Exp $
#
# FDT-based kernel configuration info
#
file arch/evbarm/fdt/fdt_dma_machdep.c fdt
file arch/evbarm/fdt/fdt_machdep.c fdt
-file arch/evbarm/fdt/fdt_memory.c fdt
include "arch/arm/fdt/files.fdt"
Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.82 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.83
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.82 Sat Nov 28 22:16:23 2020
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c Sat Dec 12 09:27:31 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.82 2020/11/28 22:16:23 riastradh Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.83 2020/12/12 09:27:31 skrll Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.82 2020/11/28 22:16:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.83 2020/12/12 09:27:31 skrll Exp $");
#include "opt_machdep.h"
#include "opt_bootconfig.h"
@@ -89,10 +89,10 @@ __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>
#include <dev/fdt/fdt_private.h>
+#include <dev/fdt/fdt_memory.h>
#ifdef EFI_RUNTIME
#include <arm/arm/efi_runtime.h>
@@ -172,81 +172,6 @@ static struct consdev earlycons = {
#define VPRINTF(...) __nothing
#endif
-/*
- * Get all of physical memory, including holes.
- */
-static void
-fdt_get_memory(uint64_t *pstart, uint64_t *pend)
-{
- const int memory = OF_finddevice("/memory");
- uint64_t cur_addr, cur_size;
- int index;
-
- /* Assume the first entry is the start of memory */
- if (fdtbus_get_reg64(memory, 0, &cur_addr, &cur_size) != 0)
- panic("Cannot determine memory size");
-
- *pstart = cur_addr;
- *pend = cur_addr + cur_size;
-
- VPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
- 0, *pstart, *pend - *pstart);
-
- for (index = 1;
- fdtbus_get_reg64(memory, index, &cur_addr, &cur_size) == 0;
- index++) {
- VPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
- index, cur_addr, cur_size);
-
- if (cur_addr + cur_size > *pend)
- *pend = cur_addr + cur_size;
- }
-}
-
-void
-fdt_add_reserved_memory_range(uint64_t addr, uint64_t size)
-{
- fdt_memory_remove_range(addr, size);
-}
-
-/*
- * Exclude memory ranges from memory config from the device tree
- */
-static void
-fdt_add_reserved_memory(uint64_t min_addr, uint64_t max_addr)
-{
- uint64_t lstart = 0, lend = 0;
- uint64_t addr, size;
- int index, error;
-
- const int num = fdt_num_mem_rsv(fdtbus_get_data());
- for (index = 0; index <= num; index++) {
- error = fdt_get_mem_rsv(fdtbus_get_data(), index,
- &addr, &size);
- if (error != 0)
- continue;
- if (lstart <= addr && addr <= lend) {
- size -= (lend - addr);
- addr = lend;
- }
- if (size == 0)
- continue;
- if (addr + size <= min_addr)
- continue;
- if (addr >= max_addr)
- continue;
- if (addr < min_addr) {
- size -= (min_addr - addr);
- addr = min_addr;
- }
- if (addr + size > max_addr)
- size = max_addr - addr;
- fdt_add_reserved_memory_range(addr, size);
- lstart = addr;
- lend = addr + size;
- }
-}
-
static void
fdt_add_dram_blocks(const struct fdt_memory *m, void *arg)
{
@@ -293,29 +218,28 @@ fdt_add_boot_physmem(const struct fdt_me
#endif
}
+
+static void
+fdt_print_memory(const struct fdt_memory *m, void *arg)
+{
+
+ VPRINTF("FDT /memory @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
+ m->start, m->end - m->start);
+}
+
+
/*
* Define usable memory regions.
*/
static void
fdt_build_bootconfig(uint64_t mem_start, uint64_t mem_end)
{
- const int memory = OF_finddevice("/memory");
BootConfig *bc = &bootconfig;
+
uint64_t addr, size;
int index;
- for (index = 0;
- fdtbus_get_reg64(memory, index, &addr, &size) == 0;
- index++) {
- if (addr >= mem_end || size == 0)
- continue;
- if (addr + size > mem_end)
- size = mem_end - addr;
-
- fdt_memory_add_range(addr, size);
- }
-
- fdt_add_reserved_memory(mem_start, mem_end);
+ fdt_memory_remove_reserved(mem_start, mem_end);
const uint64_t initrd_size =
round_page(initrd_end) - trunc_page(initrd_start);
@@ -338,7 +262,7 @@ fdt_build_bootconfig(uint64_t mem_start,
for (index = 0;
fdtbus_get_reg64(framebuffer, index, &addr, &size) == 0;
index++) {
- fdt_add_reserved_memory_range(addr, size);
+ fdt_memory_remove_range(addr, size);
}
}
@@ -576,6 +500,7 @@ initarm(void *arg)
/* If the DTB is too big, try to pack it in place first. */
if (fdt_totalsize(fdt_addr_r) > sizeof(fdt_data))
(void)fdt_pack(__UNCONST(fdt_addr_r));
+
error = fdt_open_into(fdt_addr_r, fdt_data, sizeof(fdt_data));
if (error != 0)
panic("fdt_move failed: %s", fdt_strerror(error));
@@ -656,13 +581,17 @@ initarm(void *arg)
parse_mi_bootargs(mi_bootargs);
#endif
- fdt_get_memory(&memory_start, &memory_end);
+ fdt_memory_get(&memory_start, &memory_end);
+
+ fdt_memory_foreach(fdt_print_memory, NULL);
#if !defined(_LP64)
/* Cannot map memory above 4GB (remove last page as well) */
const uint64_t memory_limit = 0x100000000ULL - PAGE_SIZE;
- if (memory_end > memory_limit)
+ if (memory_end > memory_limit) {
+ fdt_memory_remove_range(memory_limit , memory_end);
memory_end = memory_limit;
+ }
#endif
uint64_t memory_size = memory_end - memory_start;
Index: src/sys/arch/evbarm/fdt/platform.h
diff -u src/sys/arch/evbarm/fdt/platform.h:1.9 src/sys/arch/evbarm/fdt/platform.h:1.10
--- src/sys/arch/evbarm/fdt/platform.h:1.9 Sat Sep 19 16:31:40 2020
+++ src/sys/arch/evbarm/fdt/platform.h Sat Dec 12 09:27:31 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: platform.h,v 1.9 2020/09/19 16:31:40 skrll Exp $ */
+/* $NetBSD: platform.h,v 1.10 2020/12/12 09:27:31 skrll Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <[email protected]>
@@ -29,10 +29,6 @@
#ifndef _EVBARM_FDT_PLATFORM_H
#define _EVBARM_FDT_PLATFORM_H
-#ifndef _LOCORE
-void fdt_add_reserved_memory_range(uint64_t, uint64_t);
-#endif
-
#define KERNEL_IO_VBASE VM_KERNEL_IO_ADDRESS
#define KERNEL_IO_VSIZE VM_KERNEL_IO_SIZE
Index: src/sys/dev/fdt/files.fdt
diff -u src/sys/dev/fdt/files.fdt:1.56 src/sys/dev/fdt/files.fdt:1.57
--- src/sys/dev/fdt/files.fdt:1.56 Fri Oct 30 16:08:45 2020
+++ src/sys/dev/fdt/files.fdt Sat Dec 12 09:27:31 2020
@@ -1,9 +1,10 @@
-# $NetBSD: files.fdt,v 1.56 2020/10/30 16:08:45 skrll Exp $
+# $NetBSD: files.fdt,v 1.57 2020/12/12 09:27:31 skrll Exp $
include "external/bsd/libfdt/conf/files.libfdt"
defflag opt_fdt.h FDTBASE : libfdt, ofw_subr
defflag opt_fdt.h FDT: FDTBASE
+defparam opt_fdt.h FDT_MEMORY_RANGES
defparam opt_fdt.h FDT_DEFAULT_STDOUT_PATH
define fdt { [pass = 10] } : clk, pwm
@@ -53,8 +54,10 @@ device dispcon: fdt_port, drmkms, ddc_re
attach dispcon at fdt with dispcon_hdmi
file dev/fdt/hdmi_connector.c dispcon_hdmi
+file dev/fdt/fdt_memory.c fdtbase
file dev/fdt/fdt_openfirm.c fdtbase
file dev/fdt/fdt_subr.c fdtbase
+
file dev/fdt/fdt_clock.c fdt
file dev/fdt/fdt_dai.c fdt
file dev/fdt/fdt_dma.c fdt
Added files:
Index: src/sys/dev/fdt/fdt_memory.c
diff -u /dev/null src/sys/dev/fdt/fdt_memory.c:1.1
--- /dev/null Sat Dec 12 09:27:32 2020
+++ src/sys/dev/fdt/fdt_memory.c Sat Dec 12 09:27:31 2020
@@ -0,0 +1,244 @@
+/* $NetBSD: fdt_memory.c,v 1.1 2020/12/12 09:27:31 skrll 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 <[email protected]>.
+ *
+ * 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_fdt.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: fdt_memory.c,v 1.1 2020/12/12 09:27:31 skrll Exp $");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#include <libfdt.h>
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/fdt_memory.h>
+
+#ifndef FDT_MEMORY_RANGES
+#define FDT_MEMORY_RANGES 256
+#endif
+
+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[FDT_MEMORY_RANGES];
+
+static struct fdt_memory_range *
+fdt_memory_range_alloc(void)
+{
+ for (size_t n = 0; n < FDT_MEMORY_RANGES; 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 FDT_MEMORY_RANGES!\n", __func__);
+ return NULL;
+}
+
+static void
+fdt_memory_range_free(struct fdt_memory_range *mr)
+{
+ mr->mr_used = false;
+}
+
+/*
+ * Get all of physical memory, including holes.
+ */
+void
+fdt_memory_get(uint64_t *pstart, uint64_t *pend)
+{
+ const int memory = OF_finddevice("/memory");
+ uint64_t cur_addr, cur_size;
+ int index;
+
+ for (index = 0;
+ fdtbus_get_reg64(memory, index, &cur_addr, &cur_size) == 0;
+ index++) {
+ fdt_memory_add_range(cur_addr, cur_size);
+
+ /* Assume the first entry is the start of memory */
+ if (index == 0) {
+ *pstart = cur_addr;
+ *pend = cur_addr + cur_size;
+ continue;
+ }
+ if (cur_addr + cur_size > *pend)
+ *pend = cur_addr + cur_size;
+ }
+ if (index == 0)
+ panic("Cannot determine memory size");
+}
+
+/*
+ * Exclude memory ranges from memory config from the device tree
+ */
+void
+fdt_memory_remove_reserved(uint64_t min_addr, uint64_t max_addr)
+{
+ uint64_t lstart = 0, lend = 0;
+ uint64_t addr, size;
+ int index, error;
+
+ const int num = fdt_num_mem_rsv(fdtbus_get_data());
+ for (index = 0; index <= num; index++) {
+ error = fdt_get_mem_rsv(fdtbus_get_data(), index,
+ &addr, &size);
+ if (error != 0)
+ continue;
+ if (lstart <= addr && addr <= lend) {
+ size -= (lend - addr);
+ addr = lend;
+ }
+ if (size == 0)
+ continue;
+ if (addr + size <= min_addr)
+ continue;
+ if (addr >= max_addr)
+ continue;
+ if (addr < min_addr) {
+ size -= (min_addr - addr);
+ addr = min_addr;
+ }
+ if (addr + size > max_addr)
+ size = max_addr - addr;
+ fdt_memory_remove_range(addr, size);
+ lstart = addr;
+ lend = addr + size;
+ }
+}
+
+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 if (start <= mr->mr_mem.start && end > mr->mr_mem.start && end < mr->mr_mem.end) {
+ /*
+ * Partial overlap at the beginning of the range.
+ */
+ mr->mr_mem.start = end;
+ } else if (start > mr->mr_mem.start && start < mr->mr_mem.end && end >= mr->mr_mem.end) {
+ /*
+ * Partial overlap at the end of the range.
+ */
+ mr->mr_mem.end = start;
+ }
+ KASSERT(mr->mr_mem.start < mr->mr_mem.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/dev/fdt/fdt_memory.h
diff -u /dev/null src/sys/dev/fdt/fdt_memory.h:1.1
--- /dev/null Sat Dec 12 09:27:32 2020
+++ src/sys/dev/fdt/fdt_memory.h Sat Dec 12 09:27:31 2020
@@ -0,0 +1,48 @@
+/* $NetBSD: fdt_memory.h,v 1.1 2020/12/12 09:27:31 skrll 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 <[email protected]>.
+ *
+ * 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 _DEV_FDT_FDT_MEMORY_H_
+#define _DEV_FDT_FDT_MEMORY_H_
+
+struct fdt_memory {
+ uint64_t start;
+ uint64_t end;
+};
+
+void fdt_memory_init(void);
+void fdt_memory_get(uint64_t *, uint64_t *);
+void fdt_memory_add_range(uint64_t, uint64_t);
+void fdt_memory_remove_range(uint64_t, uint64_t);
+void fdt_memory_remove_reserved(uint64_t, uint64_t);
+
+void fdt_memory_foreach(void (*)(const struct fdt_memory *, void *), void *);
+
+#endif /* _DEV_FDT_FDT_MEMORY_H_ */