summaryrefslogtreecommitdiffstats
path: root/core/mem_region.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-05-19 17:05:38 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-05-21 14:41:27 +1000
commit8ab7a78c23c5e62566646aa9d5ac8749dfd73837 (patch)
tree310420a33e60e9d0c1abf48bcd35429e56bd36b3 /core/mem_region.c
parent7dabb99c1bae83091aa778b172e898d70d7d46bf (diff)
downloadblackbird-skiboot-8ab7a78c23c5e62566646aa9d5ac8749dfd73837.tar.gz
blackbird-skiboot-8ab7a78c23c5e62566646aa9d5ac8749dfd73837.zip
core: Add node-style memory reservation to device tree
Linux supports a newer memory reservation layout in the device-tree, where each reservation is represented by a subnode under a top-level "reserved-memory" node. This change adds these nodes, using the mem_region names as the property names (minus any cell addresses). The reserved-memory node looks like this: / { name = "reserved-memory"; ranges; #address-cells = <0x2>; #size-cells = <0x2>; ibm,firmware-code@30000000 { reg = <0x0 0x30000000 0x0 0x200000>; }; ibm,firmware-data@30e00000 { reg = <0x0 0x30e00000 0x0 0xc00000>; }; ibm,firmware-stacks@31a00000 { reg = <0x0 0x31a00000 0x0 0x8000000>; }; ibm,firmware-allocs-memory@39a00000 { reg = <0x0 0x39a00000 0x0 0x1c0200>; }; ibm,firmware-heap@30200000 { reg = <0x0 0x30200000 0x0 0xc00000>; }; }; We also store a pointer to the reservation nodes in struct mem_region, so they can be used by other skiboot code. We keep the property-style reservation information (reserved-names and reserved-ranges) unchanged. 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.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/core/mem_region.c b/core/mem_region.c
index ea20c5ef..0a1538dc 100644
--- a/core/mem_region.c
+++ b/core/mem_region.c
@@ -927,11 +927,30 @@ void mem_region_release_unused(void)
unlock(&mem_region_lock);
}
+static void mem_region_add_dt_reserved_node(struct dt_node *parent,
+ struct mem_region *region)
+{
+ char *name, *p;
+
+ name = strdup(region->name);
+
+ /* remove any cell addresses in the region name; we have our own cell
+ * addresses here */
+ p = strchr(name, '@');
+ if (p)
+ *p = '\0';
+
+ region->node = dt_new_addr(parent, name, region->start);
+ dt_add_property_u64s(region->node, "reg", region->start, region->len);
+ free(name);
+}
+
void mem_region_add_dt_reserved(void)
{
int names_len, ranges_len, len;
struct mem_region *region;
void *names, *ranges;
+ struct dt_node *node;
uint64_t *range;
char *name;
@@ -944,6 +963,12 @@ void mem_region_add_dt_reserved(void)
lock(&mem_region_lock);
mem_regions_finalised = true;
+ /* establish top-level reservation node */
+ node = dt_new(dt_root, "reserved-memory");
+ dt_add_property_cells(node, "#address-cells", 2);
+ dt_add_property_cells(node, "#size-cells", 2);
+ dt_add_property(node, "ranges", NULL, 0);
+
/* First pass: calculate length of property data */
list_for_each(&regions, region, list) {
if (!region_is_reserved(region))
@@ -969,6 +994,8 @@ void mem_region_add_dt_reserved(void)
(long long)(region->start + region->len - 1),
region->name);
+ mem_region_add_dt_reserved_node(node, region);
+
range[0] = cpu_to_fdt64(region->start);
range[1] = cpu_to_fdt64(region->len);
range += 2;
OpenPOWER on IntegriCloud