summaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2022-06-09 13:18:10 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-06-15 07:05:32 +0200
commitafae0a8e6524e9ca701555d7362b8a0e2df9b84e (patch)
tree7ddd2b1fe24fbc8cd7e9a600a917ce4bed61e02b /drivers/of
parentd9f85c418cab518586db146bd39e59f8aea77a14 (diff)
downloadbarebox-afae0a8e6524e9ca701555d7362b8a0e2df9b84e.tar.gz
barebox-afae0a8e6524e9ca701555d7362b8a0e2df9b84e.tar.xz
of: request reserved memory regions so other code can't
Add a new of_reserved_mem_walk that can be used to request reserved memory regions. This avoids e.g. bootm trying to place the kernel into a reserved region. Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20220609111810.2454588-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/reserved-mem.c71
2 files changed, 72 insertions, 0 deletions
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ca8da71cb4..4785128bd9 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_OF_GPIO) += of_gpio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
obj-y += partition.o
obj-y += of_net.o
+obj-y += reserved-mem.o
obj-$(CONFIG_MTD) += of_mtd.o
obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
diff --git a/drivers/of/reserved-mem.c b/drivers/of/reserved-mem.c
new file mode 100644
index 0000000000..34e61dfea3
--- /dev/null
+++ b/drivers/of/reserved-mem.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: 2021 Rouven Czerwinski <r.czerwinski@pengutronix.de>, Pengutronix
+
+#include <stdio.h>
+#include <of.h>
+#include <of_address.h>
+
+#define MEMRESERVE_NCELLS 2
+#define MEMRESERVE_FLAGS (IORESOURCE_MEM | IORESOURCE_EXCLUSIVE)
+
+int of_reserved_mem_walk(int (*handler)(const struct resource *res))
+{
+ struct device_node *node, *child;
+ int ncells = 0;
+ const __be32 *reg;
+ int ret;
+
+ node = of_find_node_by_path("/reserved-memory");
+ if (node) {
+ for_each_available_child_of_node(node, child) {
+ struct resource resource = {};
+
+ /* skip e.g. linux,cma */
+ if (!of_get_property(child, "reg", NULL))
+ continue;
+
+ of_address_to_resource(child, 0, &resource);
+
+ resource.name = child->name;
+ resource.flags = MEMRESERVE_FLAGS;
+
+ ret = handler(&resource);
+ if (ret)
+ return ret;
+ }
+ }
+
+ node = of_find_node_by_path("/memreserve");
+ reg = of_get_property(node, "reg", &ncells);
+ ncells /= sizeof(__be32);
+ if (reg) {
+ char name[sizeof "fdt-memreserve-4294967295"];
+ int i = 0, n = 0;
+
+ while (i < ncells) {
+ struct resource resource = {};
+ u64 size;
+
+ snprintf(name, sizeof(name), "fdt-memreserve-%u", n++);
+ resource.name = name;
+ resource.flags = MEMRESERVE_FLAGS;
+
+ resource.start = of_read_number(reg + i, MEMRESERVE_NCELLS);
+ i += MEMRESERVE_NCELLS;
+
+ size = of_read_number(reg + i, MEMRESERVE_NCELLS);
+ i += MEMRESERVE_NCELLS;
+
+ if (!size)
+ continue;
+
+ resource.end = resource.start + size - 1;
+
+ ret = handler(&resource);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}