diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2022-06-09 13:18:10 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-06-15 07:05:32 +0200 |
commit | afae0a8e6524e9ca701555d7362b8a0e2df9b84e (patch) | |
tree | 7ddd2b1fe24fbc8cd7e9a600a917ce4bed61e02b /drivers/of | |
parent | d9f85c418cab518586db146bd39e59f8aea77a14 (diff) | |
download | barebox-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/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/reserved-mem.c | 71 |
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; +} |