[PATCH v2 3/3] of: request reserved memory regions so other code can't
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Jun 9 04:18:10 PDT 2022
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 at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
v1 -> v2:
- don't use of_reserve_entry accounting and instead
directly request memory (Sascha)
---
common/memory.c | 21 ++++++++++--
drivers/of/Makefile | 1 +
drivers/of/reserved-mem.c | 71 +++++++++++++++++++++++++++++++++++++++
include/of.h | 9 +++++
4 files changed, 99 insertions(+), 3 deletions(-)
create mode 100644 drivers/of/reserved-mem.c
diff --git a/common/memory.c b/common/memory.c
index 95995bb6e310..fd782c7f24f6 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -3,6 +3,8 @@
* Copyright (c) 2011 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix
*/
+#define pr_fmt(fmt) "memory: " fmt
+
#include <common.h>
#include <memory.h>
#include <of.h>
@@ -12,6 +14,7 @@
#include <asm-generic/memory_layout.h>
#include <asm/sections.h>
#include <malloc.h>
+#include <of.h>
/*
* Begin and End of memory area for malloc(), and current "brk"
@@ -53,9 +56,20 @@ void mem_malloc_init(void *start, void *end)
mem_malloc_initialized = 1;
}
-#if !defined __SANDBOX__
+static int request_reservation(const struct resource *res)
+{
+ if (!(res->flags & IORESOURCE_EXCLUSIVE))
+ return 0;
+
+ pr_debug("region %s %pa-%pa\n", res->name, &res->start, &res->end);
+
+ request_sdram_region(res->name, res->start, resource_size(res));
+ return 0;
+}
+
static int mem_malloc_resource(void)
{
+#if !defined __SANDBOX__
/*
* Normally it's a bug when one of these fails,
* but we have some setups where some of these
@@ -77,13 +91,14 @@ static int mem_malloc_resource(void)
(unsigned long)&__bss_start,
(unsigned long)&__bss_stop -
(unsigned long)&__bss_start);
+#endif
#ifdef STACK_BASE
request_sdram_region("stack", STACK_BASE, STACK_SIZE);
#endif
- return 0;
+
+ return of_reserved_mem_walk(request_reservation);
}
coredevice_initcall(mem_malloc_resource);
-#endif
static void *sbrk_no_zero(ptrdiff_t increment)
{
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ca8da71cb4f0..99b610cba85e 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-$(CONFIG_OFDEVICE) += 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 000000000000..34e61dfea343
--- /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 at 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;
+}
diff --git a/include/of.h b/include/of.h
index 46b96277d581..c0b715924a18 100644
--- a/include/of.h
+++ b/include/of.h
@@ -64,6 +64,7 @@ void fdt_add_reserve_map(void *fdt);
struct device_d;
struct driver_d;
+struct resource;
int of_fix_tree(struct device_node *);
@@ -317,6 +318,9 @@ struct device_node *of_find_node_by_path_or_alias(struct device_node *root,
int of_autoenable_device_by_path(char *path);
int of_autoenable_i2c_by_component(char *path);
int of_prepend_machine_compatible(struct device_node *root, const char *compat);
+
+int of_reserved_mem_walk(int (*handler)(const struct resource *res));
+
#else
static inline bool of_node_name_eq(const struct device_node *np, const char *name)
{
@@ -841,6 +845,11 @@ static inline int of_prepend_machine_compatible(struct device_node *root,
return -ENODEV;
}
+static inline int of_reserved_mem_walk(int (*handler)(const struct resource *res))
+{
+ return 0;
+}
+
#endif
#define for_each_property_of_node(dn, pp) \
--
2.30.2
More information about the barebox
mailing list