[Skiboot] [PATCH 5/7 v3] core/mem_region: parse node-style reserved memory
Jeremy Kerr
jk at ozlabs.org
Mon Aug 17 16:49:53 AEST 2015
This change adds code to parse node-style memory reservations from the
incoming device-tree. If we find a reserved-memory node in either:
/reserved-memory/ or
/ibm,hostboot/reserved-memory
- then we use that in preference to the property-style reservations.
We copy those nodes as-is into /reserved-memory in the output tree, to
pass-through allow any extra property data that those input nodes
contain.
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
---
core/mem_region.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/core/mem_region.c b/core/mem_region.c
index f4cab8c..b85b1e3 100644
--- a/core/mem_region.c
+++ b/core/mem_region.c
@@ -803,6 +803,9 @@ static void mem_region_parse_reserved_properties(void)
const struct dt_property *names, *ranges;
struct mem_region *region;
+ prlog(PR_INFO, "MEM: parsing reserved memory from "
+ "reserved-names/-ranges properties\n");
+
names = dt_find_property(dt_root, "reserved-names");
ranges = dt_find_property(dt_root, "reserved-ranges");
if (names && ranges) {
@@ -833,11 +836,45 @@ static void mem_region_parse_reserved_properties(void)
}
}
+static bool mem_region_parse_reserved_nodes(const char *path)
+{
+ struct dt_node *parent, *node;
+
+ parent = dt_find_by_path(dt_root, path);
+ if (!parent)
+ return false;
+
+ prlog(PR_INFO, "MEM: parsing reserved memory from node %s\n", path);
+
+ dt_for_each_child(parent, node) {
+ const struct dt_property *reg;
+ struct mem_region *region;
+
+ reg = dt_find_property(node, "reg");
+ if (!reg) {
+ char *nodepath = dt_get_path(node);
+ prerror("node %s has no reg property, ignoring\n",
+ nodepath);
+ free(nodepath);
+ continue;
+ }
+
+ region = new_region(strdup(node->name),
+ dt_get_number(reg->prop, 2),
+ dt_get_number(reg->prop + sizeof(u64), 2),
+ node, REGION_HW_RESERVED);
+ list_add(®ions, ®ion->list);
+ }
+
+ return true;
+}
+
/* Trawl through device tree, create memory regions from nodes. */
void mem_region_init(void)
{
struct mem_region *region;
struct dt_node *i;
+ bool rc;
/* Ensure we have no collision between skiboot core and our heap */
extern char _end[];
@@ -895,7 +932,12 @@ void mem_region_init(void)
}
/* Add reserved ranges from the DT */
- mem_region_parse_reserved_properties();
+ rc = mem_region_parse_reserved_nodes("/reserved-memory");
+ if (!rc)
+ rc = mem_region_parse_reserved_nodes(
+ "/ibm,hostboot/reserved-memory");
+ if (!rc)
+ mem_region_parse_reserved_properties();
unlock(&mem_region_lock);
@@ -978,6 +1020,20 @@ static void mem_region_add_dt_reserved_node(struct dt_node *parent,
{
char *name, *p;
+ /* If a reserved region was established before skiboot, it may be
+ * referenced by a device-tree node with extra data. In that case,
+ * copy the node to /reserved-memory/, unless it's already there.
+ *
+ * We update region->node to the new copy here, as the prd code may
+ * update regions' device-tree nodes, and we want those updates to
+ * apply to the nodes in /reserved-memory/.
+ */
+ if (region->type == REGION_HW_RESERVED && region->node) {
+ if (region->node->parent != parent)
+ region->node = dt_copy(region->node, parent);
+ return;
+ }
+
name = strdup(region->name);
/* remove any cell addresses in the region name; we have our own cell
More information about the Skiboot
mailing list