aboutsummaryrefslogtreecommitdiff
path: root/core/mem_region.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-08-17 14:49:53 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-08-17 17:04:14 +1000
commit44088be051802fcdda2e04a2667cd3ff8b71b75a (patch)
tree8be68d9e7a1de3b6ad011b7136283f1e93c1c0a6 /core/mem_region.c
parent29f62984d7c62c9bec7eb422f6ca1e24431bd5a7 (diff)
downloadskiboot-44088be051802fcdda2e04a2667cd3ff8b71b75a.zip
skiboot-44088be051802fcdda2e04a2667cd3ff8b71b75a.tar.gz
skiboot-44088be051802fcdda2e04a2667cd3ff8b71b75a.tar.bz2
core/mem_region: parse node-style reserved memory
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@ozlabs.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/mem_region.c')
-rw-r--r--core/mem_region.c58
1 files changed, 57 insertions, 1 deletions
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(&regions, &region->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